first commit
Showing
213 changed files
with
21957 additions
and
0 deletions
**HHS animation/creative/Background.png
0 → 100644
180 KB
**HHS animation/creative/HHS_Animation.ai
0 → 100644
This diff could not be displayed because it is too large.
| 1 | /** | ||
| 2 | * VERSION: 6.03 | ||
| 3 | * DATE: 2010-08-31 | ||
| 4 | * AS3 (AS2 is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.greensock.com/overwritemanager/ | ||
| 6 | **/ | ||
| 7 | package com.greensock { | ||
| 8 | import com.greensock.core.*; | ||
| 9 | |||
| 10 | /** | ||
| 11 | * OverwriteManager resolves conflicts between tweens and controls if (and how) existing tweens of the same | ||
| 12 | * target are overwritten. Think of it as a referee or traffic cop for tweens. For example, let's say you have | ||
| 13 | * a button with <code>ROLL_OVER</code> and <code>ROLL_OUT</code> handlers that tween an object's alpha and the user rolls their mouse | ||
| 14 | * over/out/over/out quickly. Most likely, you'd want each new tween to overwrite the other immediately so | ||
| 15 | * that you don't end up with multiple tweens vying for control of the alpha property. That describes | ||
| 16 | * the <code>ALL_IMMEDIATE</code> mode which is the default mode of TweenLite when it is not used in conjunction with | ||
| 17 | * TweenMax, TimelineLite, or TimelineMax. This keeps things small and fast. However, it isn't ideal for | ||
| 18 | * setting up sequences because as soon as you create subsequent tweens of the same target in the sequence, | ||
| 19 | * the previous one gets overwritten. And what if you have a tween that is controling 3 properties and | ||
| 20 | * then you create another tween that only controls one of those properties? You may want the first tween | ||
| 21 | * to continue tweening the other 2 (non-overlapping) properties. This describes the <code>AUTO</code> mode which is | ||
| 22 | * the default whenever TweenMax, TimelineLite, or TimelineMax is used in your swf. OverwriteManager | ||
| 23 | * offers quite a few other modes to choose from in fact: | ||
| 24 | * | ||
| 25 | * <ul> | ||
| 26 | * <li><b> NONE (0):</b> | ||
| 27 | * <ol> | ||
| 28 | * <li><b>When:</b> Never</li> | ||
| 29 | * <li><b>Finds:</b> Nothing</li> | ||
| 30 | * <li><b>Kills:</b> Nothing</li> | ||
| 31 | * <li><b>Performance:</b> Excellent</li> | ||
| 32 | * <li><b>Good for:</b> When you know that your tweens won't conflict and you want maximum speed.</li> | ||
| 33 | * </ol> | ||
| 34 | * </li> | ||
| 35 | * | ||
| 36 | * <li><b> ALL_IMMEDIATE (1):</b> | ||
| 37 | * <ol> | ||
| 38 | * <li><b>When:</b> Immediately when the tween is created.</li> | ||
| 39 | * <li><b>Finds:</b> All tweens of the same target (regardless of timing or overlapping properties).</li> | ||
| 40 | * <li><b>Kills:</b> Every tween found</li> | ||
| 41 | * <li><b>Performance:</b> Excellent</li> | ||
| 42 | * <li><b>Good for:</b> When you want the tween to take priority over all other tweens of the | ||
| 43 | * same target, like on button rollovers/rollouts. However, this mode is | ||
| 44 | * bad for setting up sequences.</li> | ||
| 45 | * </ol> | ||
| 46 | * This is the default mode for TweenLite unless TweenMax, TimelineLite, | ||
| 47 | * or TimelineMax are used in the SWF (in which case <code>AUTO</code> is the default mode). | ||
| 48 | * </li> | ||
| 49 | * | ||
| 50 | * <li><b> AUTO (2):</b> | ||
| 51 | * <ol> | ||
| 52 | * <li><b>When:</b> The first time the tween renders (you can <code>invalidate()</code> a tween to force it | ||
| 53 | * to re-init and run its overwriting routine again next time it renders)</li> | ||
| 54 | * <li><b>Finds:</b> Only tweens of the same target that are active (running). Tweens that haven't started yet are immune.</li> | ||
| 55 | * <li><b>Kills:</b> Only individual overlapping tweening properties. If all tweening properties | ||
| 56 | * have been overwritten, the entire tween will be killed as well.</li> | ||
| 57 | * <li><b>Performance:</b> Very good when there aren't many overlapping tweens; fair when there are.</li> | ||
| 58 | * <li><b>Good for:</b> Virtually all situations. This mode does the best job overall of handling | ||
| 59 | * overwriting in an intuitive way and is excellent for sequencing. </li> | ||
| 60 | * </ol> | ||
| 61 | * This is the default mode when TweenMax, TimelineLite, or TimelineMax is used in your swf (those classes | ||
| 62 | * automatically init() OverwriteManager in <code>AUTO</code> mode unless you have already initted OverwriteManager manually). | ||
| 63 | * </li> | ||
| 64 | * | ||
| 65 | * <li><b> CONCURRENT (3):</b> | ||
| 66 | * <ol> | ||
| 67 | * <li><b>When:</b> The first time the tween renders (you can <code>invalidate()</code> a tween to force it | ||
| 68 | * to re-init and run its overwriting routine again next time it renders)</li> | ||
| 69 | * <li><b>Finds:</b> Only tweens of the same target that are active (running). Tweens that haven't started yet are immune.</li> | ||
| 70 | * <li><b>Kills:</b> Every tween found</li> | ||
| 71 | * <li><b>Performance:</b> Very good</li> | ||
| 72 | * <li><b>Good for:</b> When you want the target object to only be controled by one tween at a time. Good | ||
| 73 | * for sequencing although AUTO mode is typically better because it will only kill | ||
| 74 | * individual overlapping properties instead of entire tweens.</li> | ||
| 75 | * </ol> | ||
| 76 | * </li> | ||
| 77 | * | ||
| 78 | * <li><b> ALL_ONSTART (4):</b> | ||
| 79 | * <ol> | ||
| 80 | * <li><b>When:</b> The first time the tween renders (you can <code>invalidate()</code> a tween to force it | ||
| 81 | * to re-init and run its overwriting routine again next time it renders)</li> | ||
| 82 | * <li><b>Finds:</b> All tweens of the same target (regardless of timing or overlapping properties).</li> | ||
| 83 | * <li><b>Kills:</b> Every tween found</li> | ||
| 84 | * <li><b>Performance:</b> Very good</li> | ||
| 85 | * <li><b>Good for:</b> When you want a tween to take priority and wipe out all other tweens of the | ||
| 86 | * same target even if they start later. This mode is rarely used.</li> | ||
| 87 | * </ol> | ||
| 88 | * </li> | ||
| 89 | * | ||
| 90 | * <li><b> PREEXISTING (5):</b> | ||
| 91 | * <ol> | ||
| 92 | * <li><b>When:</b> The first time the tween renders (you can <code>invalidate()</code> a tween to force it | ||
| 93 | * to re-init and run its overwriting routine again next time it renders)</li> | ||
| 94 | * <li><b>Finds:</b> Only the tweens of the same target that were created before this tween was created | ||
| 95 | * (regardless of timing or overlapping properties). Virtually identical to <code>ALL_IMMEDIATE</code> | ||
| 96 | * except that <code>PREEXISTING</code> doesn't run its overwriting routines until it renders for the | ||
| 97 | * first time, meaning that if it has a delay, other tweens won't be overwritten until the delay expires.</li> | ||
| 98 | * <li><b>Kills:</b> Every tween found</li> | ||
| 99 | * <li><b>Performance:</b> Very good</li> | ||
| 100 | * <li><b>Good for:</b> When the order in which your code runs plays a critical role, like when tweens | ||
| 101 | * that you create later should always take precidence over previously created ones | ||
| 102 | * regardless of when they're scheduled to run. If <code>ALL_IMMEDIATE</code> is great except | ||
| 103 | * that you want to wait on overwriting until the tween begins, <code>PREEXISTING</code> is perfect.</li> | ||
| 104 | * </ol> | ||
| 105 | * </li> | ||
| 106 | * </ul> | ||
| 107 | * | ||
| 108 | * With the exception of <code>ALL_IMMEDIATE</code> (which performs overwriting immediatly when the tween is created), | ||
| 109 | * all overwriting occurs when a tween renders for the first time. So if your tween has a delay of 1 second, | ||
| 110 | * it will not overwrite any tweens until that point. <br /><br /> | ||
| 111 | * | ||
| 112 | * You can define a default overwriting mode for all tweens using the <code>OverwriteManager.init()</code> method, like:<br /><br /><code> | ||
| 113 | * | ||
| 114 | * OverwriteManager.init(OverwriteManager.AUTO);<br /><br /></code> | ||
| 115 | * | ||
| 116 | * If you want to override the default mode in a particular tween, just use the <code>overwrite</code> special | ||
| 117 | * property. You can use the static constant or the corresponding number. The following two lines produce | ||
| 118 | * the same results:<br /><br /><code> | ||
| 119 | * | ||
| 120 | * TweenMax.to(mc, 1, {x:100, overwrite:OverwriteManager.PREXISTING});<br /> | ||
| 121 | * TweenMax.to(mc, 1, {x:100, overwrite:5});<br /><br /></code> | ||
| 122 | * | ||
| 123 | * OverwriteManager is a separate, optional class for TweenLite primarily because of file size concerns. | ||
| 124 | * Without initting OverwriteManager, TweenLite can only recognize modes 0 and 1 (<code>NONE</code> and <code>ALL_IMMEDIATE</code>). | ||
| 125 | * However, TweenMax, TimelineLite, and TimelineMax automatically init() OverwriteManager in <code>AUTO</code> mode | ||
| 126 | * unless you have already initted OverwriteManager manually. You do not need to take any additional steps | ||
| 127 | * to use AUTO mode if you're using any of those classes somewhere in your project. Keep in mind too that setting | ||
| 128 | * the default OverwriteManager mode will affect TweenLite and TweenMax tweens.<br /><br /> | ||
| 129 | * | ||
| 130 | * | ||
| 131 | * <b>EXAMPLES:</b><br /><br /> | ||
| 132 | * | ||
| 133 | * To start OverwriteManager in <code>AUTO</code> mode (the default) and then do a simple TweenLite tween, simply do:<br /><br /><code> | ||
| 134 | * | ||
| 135 | * import com.greensock.OverwriteManager;<br /> | ||
| 136 | * import com.greensock.TweenLite;<br /><br /> | ||
| 137 | * | ||
| 138 | * OverwriteManager.init(OverwriteManager.AUTO);<br /> | ||
| 139 | * TweenLite.to(mc, 2, {x:300});<br /><br /></code> | ||
| 140 | * | ||
| 141 | * You can also define overwrite behavior in individual tweens, like so:<br /><br /><code> | ||
| 142 | * | ||
| 143 | * import com.greensock.OverwriteManager;<br /> | ||
| 144 | * import com.greensock.TweenLite;<br /><br /> | ||
| 145 | * | ||
| 146 | * OverwriteManager.init(2);<br /> | ||
| 147 | * TweenLite.to(mc, 2, {x:"300", y:"100"});<br /> | ||
| 148 | * TweenLite.to(mc, 1, {alpha:0.5, overwrite:1}); //or use the constant OverwriteManager.ALL_IMMEDIATE<br /> | ||
| 149 | * TweenLite.to(mc, 3, {x:200, rotation:30, overwrite:2}); //or use the constant OverwriteManager.AUTO<br /><br /></code> | ||
| 150 | * | ||
| 151 | * | ||
| 152 | * OverwriteManager's mode can be changed anytime after init() is called, like.<br /><br /><code> | ||
| 153 | * | ||
| 154 | * OverwriteManager.mode = OverwriteManager.CONCURRENT;<br /><br /></code> | ||
| 155 | * | ||
| 156 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 157 | * | ||
| 158 | * @author Jack Doyle, jack@greensock.com | ||
| 159 | */ | ||
| 160 | public class OverwriteManager { | ||
| 161 | /** @private **/ | ||
| 162 | public static const version:Number = 6.03; | ||
| 163 | /** Won't overwrite any other tweens **/ | ||
| 164 | public static const NONE:int = 0; | ||
| 165 | /** Overwrites all existing tweens of the same target immediately when the tween is created **/ | ||
| 166 | public static const ALL_IMMEDIATE:int = 1; | ||
| 167 | /** Only overwrites individual overlapping tweening properties in other tweens of the same target. TweenMax, TimelineLite, and TimelineMax automatically init() OverwriteManager in this mode if you haven't already called OverwriteManager.init(). **/ | ||
| 168 | public static const AUTO:int = 2; | ||
| 169 | /** Overwrites tweens of the same target that are active when the tween renders for the first time. **/ | ||
| 170 | public static const CONCURRENT:int = 3; | ||
| 171 | /** Overwrites all tweens of the same target (regardless of overlapping properties or timing) when the tween renders for the first time as opposed to ALL_IMMEDIATE which performs overwriting immediately when the tween is created. **/ | ||
| 172 | public static const ALL_ONSTART:int = 4; | ||
| 173 | /** Overwrites tweens of the same target that existed before this tween regardless of their start/end time or active state or overlapping properties. **/ | ||
| 174 | public static const PREEXISTING:int = 5; | ||
| 175 | /** The default overwrite mode for all TweenLite and TweenMax instances **/ | ||
| 176 | public static var mode:int; | ||
| 177 | /** @private **/ | ||
| 178 | public static var enabled:Boolean; | ||
| 179 | |||
| 180 | /** | ||
| 181 | * Initializes OverwriteManager and sets the default management mode. Options include: | ||
| 182 | * <ul> | ||
| 183 | * <li><b> NONE (0):</b> | ||
| 184 | * <ol> | ||
| 185 | * <li><b>When:</b> Never</li> | ||
| 186 | * <li><b>Finds:</b> Nothing</li> | ||
| 187 | * <li><b>Kills:</b> Nothing</li> | ||
| 188 | * <li><b>Performance:</b> Excellent</li> | ||
| 189 | * <li><b>Good for:</b> When you know that your tweens won't conflict and you want maximum speed.</li> | ||
| 190 | * </ol> | ||
| 191 | * </li> | ||
| 192 | * | ||
| 193 | * <li><b> ALL_IMMEDIATE (1):</b> | ||
| 194 | * <ol> | ||
| 195 | * <li><b>When:</b> Immediately when the tween is created.</li> | ||
| 196 | * <li><b>Finds:</b> All tweens of the same target (regardless of timing or overlapping properties).</li> | ||
| 197 | * <li><b>Kills:</b> Every tween found</li> | ||
| 198 | * <li><b>Performance:</b> Excellent</li> | ||
| 199 | * <li><b>Good for:</b> When you want the tween to take priority over all other tweens of the | ||
| 200 | * same target, like on button rollovers/rollouts. However, this mode is | ||
| 201 | * bad for setting up sequences.</li> | ||
| 202 | * </ol> | ||
| 203 | * This is the default mode for TweenLite unless TweenMax, TimelineLite, | ||
| 204 | * or TimelineMax are used in the SWF (in which case <code>AUTO</code> is the default mode). | ||
| 205 | * </li> | ||
| 206 | * | ||
| 207 | * <li><b> AUTO (2):</b> | ||
| 208 | * <ol> | ||
| 209 | * <li><b>When:</b> The first time the tween renders (you can <code>invalidate()</code> a tween to force it | ||
| 210 | * to re-init and run its overwriting routine again next time it renders)</li> | ||
| 211 | * <li><b>Finds:</b> Only tweens of the same target that are active (running). Tweens that haven't started yet are immune.</li> | ||
| 212 | * <li><b>Kills:</b> Only individual overlapping tweening properties. If all tweening properties | ||
| 213 | * have been overwritten, the entire tween will be killed as well.</li> | ||
| 214 | * <li><b>Performance:</b> Very good when there aren't many overlapping tweens; fair when there are.</li> | ||
| 215 | * <li><b>Good for:</b> Virtually all situations. This mode does the best job overall of handling | ||
| 216 | * overwriting in an intuitive way and is excellent for sequencing. </li> | ||
| 217 | * </ol> | ||
| 218 | * This is the default mode when TweenMax, TimelineLite, or TimelineMax is used in your swf (those classes | ||
| 219 | * automatically init() OverwriteManager in <code>AUTO</code> mode unless you have already initted OverwriteManager manually). | ||
| 220 | * </li> | ||
| 221 | * | ||
| 222 | * <li><b> CONCURRENT (3):</b> | ||
| 223 | * <ol> | ||
| 224 | * <li><b>When:</b> The first time the tween renders (you can <code>invalidate()</code> a tween to force it | ||
| 225 | * to re-init and run its overwriting routine again next time it renders)</li> | ||
| 226 | * <li><b>Finds:</b> Only tweens of the same target that are active (running). Tweens that haven't started yet are immune.</li> | ||
| 227 | * <li><b>Kills:</b> Every tween found</li> | ||
| 228 | * <li><b>Performance:</b> Very good</li> | ||
| 229 | * <li><b>Good for:</b> When you want the target object to only be controled by one tween at a time. Good | ||
| 230 | * for sequencing although AUTO mode is typically better because it will only kill | ||
| 231 | * individual overlapping properties instead of entire tweens.</li> | ||
| 232 | * </ol> | ||
| 233 | * </li> | ||
| 234 | * | ||
| 235 | * <li><b> ALL_ONSTART (4):</b> | ||
| 236 | * <ol> | ||
| 237 | * <li><b>When:</b> The first time the tween renders (you can <code>invalidate()</code> a tween to force it | ||
| 238 | * to re-init and run its overwriting routine again next time it renders)</li> | ||
| 239 | * <li><b>Finds:</b> All tweens of the same target (regardless of timing or overlapping properties).</li> | ||
| 240 | * <li><b>Kills:</b> Every tween found</li> | ||
| 241 | * <li><b>Performance:</b> Very good</li> | ||
| 242 | * <li><b>Good for:</b> When you want a tween to take priority and wipe out all other tweens of the | ||
| 243 | * same target even if they start later. This mode is rarely used.</li> | ||
| 244 | * </ol> | ||
| 245 | * </li> | ||
| 246 | * | ||
| 247 | * <li><b> PREEXISTING (5):</b> | ||
| 248 | * <ol> | ||
| 249 | * <li><b>When:</b> The first time the tween renders (you can <code>invalidate()</code> a tween to force it | ||
| 250 | * to re-init and run its overwriting routine again next time it renders)</li> | ||
| 251 | * <li><b>Finds:</b> Only the tweens of the same target that were created before this tween was created | ||
| 252 | * (regardless of timing or overlapping properties). Virtually identical to <code>ALL_IMMEDIATE</code> | ||
| 253 | * except that <code>PREEXISTING</code> doesn't run its overwriting routines until it renders for the | ||
| 254 | * first time, meaning that if it has a delay, other tweens won't be overwritten until the delay expires.</li> | ||
| 255 | * <li><b>Kills:</b> Every tween found</li> | ||
| 256 | * <li><b>Performance:</b> Very good</li> | ||
| 257 | * <li><b>Good for:</b> When the order in which your code runs plays a critical role, like when tweens | ||
| 258 | * that you create later should always take precidence over previously created ones | ||
| 259 | * regardless of when they're scheduled to run. If <code>ALL_IMMEDIATE</code> is great except | ||
| 260 | * that you want to wait on overwriting until the tween begins, <code>PREEXISTING</code> is perfect.</li> | ||
| 261 | * </ol> | ||
| 262 | * </li> | ||
| 263 | * </ul> | ||
| 264 | * | ||
| 265 | * @param defaultMode The default mode that OverwriteManager should use. | ||
| 266 | **/ | ||
| 267 | public static function init(defaultMode:int=2):int { | ||
| 268 | if (TweenLite.version < 11.1) { | ||
| 269 | throw new Error("Warning: Your TweenLite class needs to be updated to work with OverwriteManager (or you may need to clear your ASO files). Please download and install the latest version from http://www.tweenlite.com."); | ||
| 270 | } | ||
| 271 | TweenLite.overwriteManager = OverwriteManager; | ||
| 272 | mode = defaultMode; | ||
| 273 | enabled = true; | ||
| 274 | return mode; | ||
| 275 | } | ||
| 276 | |||
| 277 | /** | ||
| 278 | * @private | ||
| 279 | * @return Boolean value indicating whether or not properties may have changed on the target when overwriting occurred. For example, when a motionBlur (plugin) is disabled, it swaps out a BitmapData for the target and may alter the alpha. We need to know this in order to determine whether or not the new tween should be re-initted() with the changed properties. | ||
| 280 | **/ | ||
| 281 | public static function manageOverwrites(tween:TweenLite, props:Object, targetTweens:Array, mode:uint):Boolean { | ||
| 282 | var i:int, changed:Boolean, curTween:TweenLite; | ||
| 283 | if (mode >= 4) { | ||
| 284 | var l:uint = targetTweens.length; | ||
| 285 | for (i = 0; i < l; i++) { | ||
| 286 | curTween = targetTweens[i]; | ||
| 287 | if (curTween != tween) { | ||
| 288 | if (curTween.setEnabled(false, false)) { | ||
| 289 | changed = true; | ||
| 290 | } | ||
| 291 | } else if (mode == 5) { | ||
| 292 | break; | ||
| 293 | } | ||
| 294 | } | ||
| 295 | return changed; | ||
| 296 | } | ||
| 297 | //NOTE: Add 0.0000000001 to overcome floating point errors that can cause the startTime to be VERY slightly off (when a tween's currentTime property is set for example) | ||
| 298 | var startTime:Number = tween.cachedStartTime + 0.0000000001, overlaps:Array = [], cousins:Array = [], cCount:uint = 0, oCount:uint = 0; | ||
| 299 | i = targetTweens.length; | ||
| 300 | while (--i > -1) { | ||
| 301 | curTween = targetTweens[i]; | ||
| 302 | if (curTween == tween || curTween.gc) { | ||
| 303 | //ignore | ||
| 304 | } else if (curTween.timeline != tween.timeline) { | ||
| 305 | if (!getGlobalPaused(curTween)) { | ||
| 306 | cousins[cCount++] = curTween; | ||
| 307 | } | ||
| 308 | } else if (curTween.cachedStartTime <= startTime && curTween.cachedStartTime + curTween.totalDuration + 0.0000000001 > startTime && !getGlobalPaused(curTween)) { | ||
| 309 | overlaps[oCount++] = curTween; | ||
| 310 | } | ||
| 311 | } | ||
| 312 | |||
| 313 | if (cCount != 0) { //tweens that are nested in other timelines may have various offsets and timeScales so we need to translate them to a global/root one to see how they compare. | ||
| 314 | var combinedTimeScale:Number = tween.cachedTimeScale, combinedStartTime:Number = startTime, cousin:TweenCore, cousinStartTime:Number, timeline:SimpleTimeline; | ||
| 315 | timeline = tween.timeline; | ||
| 316 | while (timeline) { | ||
| 317 | combinedTimeScale *= timeline.cachedTimeScale; | ||
| 318 | combinedStartTime += timeline.cachedStartTime; | ||
| 319 | timeline = timeline.timeline; | ||
| 320 | } | ||
| 321 | startTime = combinedTimeScale * combinedStartTime; | ||
| 322 | i = cCount; | ||
| 323 | while (--i > -1) { | ||
| 324 | cousin = cousins[i]; | ||
| 325 | combinedTimeScale = cousin.cachedTimeScale; | ||
| 326 | combinedStartTime = cousin.cachedStartTime; | ||
| 327 | timeline = cousin.timeline; | ||
| 328 | while (timeline) { | ||
| 329 | combinedTimeScale *= timeline.cachedTimeScale; | ||
| 330 | combinedStartTime += timeline.cachedStartTime; | ||
| 331 | timeline = timeline.timeline; | ||
| 332 | } | ||
| 333 | cousinStartTime = combinedTimeScale * combinedStartTime; | ||
| 334 | if (cousinStartTime <= startTime && (cousinStartTime + (cousin.totalDuration * combinedTimeScale) + 0.0000000001 > startTime || cousin.cachedDuration == 0)) { | ||
| 335 | overlaps[oCount++] = cousin; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | if (oCount == 0) { | ||
| 341 | return changed; | ||
| 342 | } | ||
| 343 | |||
| 344 | i = oCount; | ||
| 345 | if (mode == 2) { | ||
| 346 | while (--i > -1) { | ||
| 347 | curTween = overlaps[i]; | ||
| 348 | if (curTween.killVars(props)) { | ||
| 349 | changed = true; | ||
| 350 | } | ||
| 351 | if (curTween.cachedPT1 == null && curTween.initted) { | ||
| 352 | curTween.setEnabled(false, false); //if all property tweens have been overwritten, kill the tween. | ||
| 353 | } | ||
| 354 | } | ||
| 355 | |||
| 356 | } else { | ||
| 357 | while (--i > -1) { | ||
| 358 | if (TweenLite(overlaps[i]).setEnabled(false, false)) { //flags for garbage collection | ||
| 359 | changed = true; | ||
| 360 | } | ||
| 361 | } | ||
| 362 | } | ||
| 363 | return changed; | ||
| 364 | } | ||
| 365 | |||
| 366 | /** @private **/ | ||
| 367 | public static function getGlobalPaused(tween:TweenCore):Boolean { | ||
| 368 | var paused:Boolean; | ||
| 369 | while (tween) { | ||
| 370 | if (tween.cachedPaused) { | ||
| 371 | paused = true; //we don't just return true immediately here because of an odd bug in Flash that could (in EXTREMELY rare circumstances) throw an error. | ||
| 372 | break; | ||
| 373 | } | ||
| 374 | tween = tween.timeline; | ||
| 375 | } | ||
| 376 | return paused; | ||
| 377 | } | ||
| 378 | |||
| 379 | } | ||
| 380 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.382 | ||
| 3 | * DATE: 2010-05-25 | ||
| 4 | * AS3 (AS2 version is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.greensock.com/timelinelite/ | ||
| 6 | **/ | ||
| 7 | package com.greensock { | ||
| 8 | import com.greensock.core.*; | ||
| 9 | |||
| 10 | import flash.utils.*; | ||
| 11 | /** | ||
| 12 | * TimelineLite is a lightweight, intuitive timeline class for building and managing sequences of | ||
| 13 | * TweenLite, TweenMax, TimelineLite, and/or TimelineMax instances. You can think of a TimelineLite instance | ||
| 14 | * like a virtual MovieClip timeline or a container where you place tweens (or other timelines) over the | ||
| 15 | * course of time. You can: | ||
| 16 | * <ul> | ||
| 17 | * <li> build sequences easily by adding tweens with the append(), prepend(), insert(), appendMultiple(), prependMultiple(), | ||
| 18 | * and insertMultiple() methods. Tweens can overlap as much as you want and you have complete control over where | ||
| 19 | * they get placed on the timeline.</li> | ||
| 20 | * | ||
| 21 | * <li> add labels, play(), stop(), gotoAndPlay(), gotoAndStop(), restart(), and even reverse() smoothly anytime. </li> | ||
| 22 | * | ||
| 23 | * <li> nest timelines within timelines as deeply as you want.</li> | ||
| 24 | * | ||
| 25 | * <li> set the progress of the timeline using its <code>currentProgress</code> property. For example, to skip to | ||
| 26 | * the halfway point, set <code>myTimeline.currentProgress = 0.5</code>. </li> | ||
| 27 | * | ||
| 28 | * <li> tween the <code>currentTime</code> or <code>currentProgress</code> property to fastforward/rewind | ||
| 29 | * the timeline. You could even attach a slider to one of these properties to give the user the ability | ||
| 30 | * to drag forwards/backwards through the timeline.</li> | ||
| 31 | * | ||
| 32 | * <li> speed up or slow down the entire timeline with its timeScale property. You can even tween | ||
| 33 | * this property to gradually speed up or slow down.</li> | ||
| 34 | * | ||
| 35 | * <li> add onComplete, onStart, onUpdate, and/or onReverseComplete callbacks using the constructor's <code>vars</code> object.</li> | ||
| 36 | * | ||
| 37 | * <li> use the <code>insertMultiple()</code> or <code>appendMultiple()</code> methods to create complex sequences including | ||
| 38 | * various alignment modes and staggering capabilities.</li> | ||
| 39 | * | ||
| 40 | * <li> base the timing on frames instead of seconds if you prefer. Please note, however, that | ||
| 41 | * the timeline's timing mode dictates its childrens' timing mode as well. </li> | ||
| 42 | * | ||
| 43 | * <li> kill the tweens of a particular object with <code>killTweensOf()</code> or get the tweens of an object | ||
| 44 | * with <code>getTweensOf()</code> or get all the tweens/timelines in the timeline with <code>getChildren()</code></li> | ||
| 45 | * | ||
| 46 | * <li> If you need even more features like AS3 event listeners, <code>repeat, repeatDelay, yoyo, currentLabel, | ||
| 47 | * getLabelAfter(), getLabelBefore(), addCallback(), removeCallback(), getActive()</code> and more, check out | ||
| 48 | * TimelineMax which extends TimelineLite.</li> | ||
| 49 | * </ul> | ||
| 50 | * | ||
| 51 | * <b>EXAMPLE:</b><br /><br /><code> | ||
| 52 | * | ||
| 53 | * import com.greensock.~~;<br /><br /> | ||
| 54 | * | ||
| 55 | * //create the timeline and add an onComplete callback that will call myFunction() when the timeline completes<br /> | ||
| 56 | * var myTimeline:TimelineLite = new TimelineLite({onComplete:myFunction});<br /><br /> | ||
| 57 | * | ||
| 58 | * //add a tween<br /> | ||
| 59 | * myTimeline.append(new TweenLite(mc, 1, {x:200, y:100}));<br /><br /> | ||
| 60 | * | ||
| 61 | * //add another tween at the end of the timeline (makes sequencing easy)<br /> | ||
| 62 | * myTimeline.append(new TweenLite(mc, 0.5, {alpha:0}));<br /><br /> | ||
| 63 | * | ||
| 64 | * //reverse anytime<br /> | ||
| 65 | * myTimeline.reverse();<br /><br /> | ||
| 66 | * | ||
| 67 | * //Add a "spin" label 3-seconds into the timeline<br /> | ||
| 68 | * myTimeline.addLabel("spin", 3);<br /><br /> | ||
| 69 | * | ||
| 70 | * //insert a rotation tween at the "spin" label (you could also define the insert point as the time instead of a label)<br /> | ||
| 71 | * myTimeline.insert(new TweenLite(mc, 2, {rotation:"360"}), "spin"); <br /><br /> | ||
| 72 | * | ||
| 73 | * //go to the "spin" label and play the timeline from there<br /> | ||
| 74 | * myTimeline.gotoAndPlay("spin");<br /><br /> | ||
| 75 | * | ||
| 76 | * //add a tween to the beginning of the timeline, pushing all the other existing tweens back in time<br /> | ||
| 77 | * myTimeline.prepend(new TweenMax(mc, 1, {tint:0xFF0000}));<br /><br /> | ||
| 78 | * | ||
| 79 | * //nest another TimelineLite inside your timeline...<br /> | ||
| 80 | * var nestedTimeline:TimelineLite = new TimelineLite();<br /> | ||
| 81 | * nestedTimeline.append(new TweenLite(mc2, 1, {x:200}));<br /> | ||
| 82 | * myTimeline.append(nestedTimeline);<br /><br /></code> | ||
| 83 | * | ||
| 84 | * | ||
| 85 | * insertMultiple() and appendMultiple() provide some very powerful sequencing tools, allowing you to add an Array of | ||
| 86 | * tweens or timelines and optionally align them with SEQUENCE or START modes, and even stagger them if you want. | ||
| 87 | * For example, to insert 3 tweens into the timeline, aligning their start times but staggering them by 0.2 seconds, <br /><br /><code> | ||
| 88 | * | ||
| 89 | * myTimeline.insertMultiple([new TweenLite(mc, 1, {y:"100"}), | ||
| 90 | * new TweenLite(mc2, 1, {x:20}), | ||
| 91 | * new TweenLite(mc3, 1, {alpha:0.5})], | ||
| 92 | * 0, | ||
| 93 | * TweenAlign.START, | ||
| 94 | * 0.2);</code><br /><br /> | ||
| 95 | * | ||
| 96 | * You can use the constructor's "vars" object to do virtually all the setup too, like this sequence:<br /><br /><code> | ||
| 97 | * | ||
| 98 | * var myTimeline:TimelineLite = new TimelineLite({tweens:[new TweenLite(mc1, 1, {y:"100"}), TweenMax.to(mc2, 1, {tint:0xFF0000})], align:TweenAlign.SEQUENCE, onComplete:myFunction});</code><br /><br /> | ||
| 99 | * | ||
| 100 | * If that confuses you, don't worry. Just use the <code>append(), insert()</code>, and <code>prepend()</code> methods to build your | ||
| 101 | * sequence. But power users will likely appreciate the quick, compact way they can set up sequences now. <br /><br /> | ||
| 102 | * | ||
| 103 | * | ||
| 104 | * <b>NOTES:</b> | ||
| 105 | * <ul> | ||
| 106 | * <li> TimelineLite automatically inits the OverwriteManager class to prevent unexpected overwriting behavior in sequences. | ||
| 107 | * The default mode is <code>AUTO</code>, but you can set it to whatever you want with <code>OverwriteManager.init()</code> | ||
| 108 | * (see <a href="http://www.greensock.com/overwritemanager/">http://www.greensock.com/overwritemanager/</a>)</li> | ||
| 109 | * <li> TimelineLite adds about 2.6k to your SWF (3.3kb including OverwriteManager).</li> | ||
| 110 | * </ul> | ||
| 111 | * | ||
| 112 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 113 | * | ||
| 114 | * @author Jack Doyle, jack@greensock.com | ||
| 115 | **/ | ||
| 116 | public class TimelineLite extends SimpleTimeline { | ||
| 117 | /** @private **/ | ||
| 118 | public static const version:Number = 1.382; | ||
| 119 | /** @private **/ | ||
| 120 | private static var _overwriteMode:int = (OverwriteManager.enabled) ? OverwriteManager.mode : OverwriteManager.init(2); //Ensures that TweenLite instances don't overwrite each other before being put into the timeline/sequence. | ||
| 121 | /** @private **/ | ||
| 122 | protected var _labels:Object; | ||
| 123 | /** @private Just stores the first and last tweens when the timeline is disabled (enabled=false). We do this in an Array in order to avoid circular references which can cause garbage collection issues (timeline referencing TweenCore, and TweenCore referencing timeline) **/ | ||
| 124 | protected var _endCaps:Array; | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Constructor. <br /><br /> | ||
| 128 | * | ||
| 129 | * <b>SPECIAL PROPERTIES</b><br /> | ||
| 130 | * The following special properties may be passed in via the constructor's vars parameter, like | ||
| 131 | * <code>new TimelineLite({paused:true, onComplete:myFunction})</code> | ||
| 132 | * | ||
| 133 | * <ul> | ||
| 134 | * <li><b> delay : Number</b> Amount of delay in seconds (or frames for frames-based timelines) before the timeline should begin.</li> | ||
| 135 | * | ||
| 136 | * <li><b> paused : Boolean</b> Sets the initial paused state of the timeline (by default, timelines automatically begin playing immediately)</li> | ||
| 137 | * | ||
| 138 | * <li><b> useFrames : Boolean</b> If useFrames is set to true, the timeline's timing mode will be based on frames. | ||
| 139 | * Otherwise, it will be based on seconds/time. NOTE: a TimelineLite's timing mode is | ||
| 140 | * always determined by its parent timeline. </li> | ||
| 141 | * | ||
| 142 | * <li><b> reversed : Boolean</b> If true, the timeline will be reversed initially. This does NOT force it to the very end and start | ||
| 143 | * playing backwards. It simply affects the orientation of the timeline, so if reversed is set to | ||
| 144 | * true initially, it will appear not to play because it is already at the beginning. To cause it to | ||
| 145 | * play backwards from the end, set reversed to true and then set the <code>currentProgress</code> property to 1 immediately | ||
| 146 | * after creating the timeline.</li> | ||
| 147 | * | ||
| 148 | * <li><b> tweens : Array</b> To immediately insert several tweens into the timeline, use the <code>tweens</code> special property | ||
| 149 | * to pass in an Array of TweenLite/TweenMax/TimelineLite/TimelineMax instances. You can use this in conjunction | ||
| 150 | * with the align and stagger special properties to set up complex sequences with minimal code. | ||
| 151 | * These values simply get passed to the insertMultiple() method.</li> | ||
| 152 | * | ||
| 153 | * <li><b> align : String</b> Only used in conjunction with the <code>tweens</code> special property when multiple tweens are | ||
| 154 | * to be inserted immediately. The value simply gets passed to the | ||
| 155 | * <code>insertMultiple()</code> method. The default is <code>TweenAlign.NORMAL</code>. Options are: | ||
| 156 | * <ul> | ||
| 157 | * <li><b> TweenAlign.SEQUENCE:</b> aligns the tweens one-after-the-other in a sequence</li> | ||
| 158 | * <li><b> TweenAlign.START:</b> aligns the start times of all of the tweens (ignores delays)</li> | ||
| 159 | * <li><b> TweenAlign.NORMAL:</b> aligns the start times of all the tweens (honors delays)</li> | ||
| 160 | * </ul>The <code>align</code> special property does <b>not</b> force all child tweens/timelines to maintain | ||
| 161 | * relative positioning, so for example, if you use TweenAlign.SEQUENCE and then later change the duration | ||
| 162 | * of one of the nested tweens, it does <b>not</b> force all subsequent timelines to change their position | ||
| 163 | * on the timeline. The <code>align</code> special property only affects the alignment of the tweens that are | ||
| 164 | * initially placed into the timeline through the <code>tweens</code> special property of the <code>vars</code> object.</li> | ||
| 165 | * | ||
| 166 | * <li><b> stagger : Number</b> Only used in conjunction with the <code>tweens</code> special property when multiple tweens are | ||
| 167 | * to be inserted immediately. It staggers the tweens by a set amount of time (in seconds) (or | ||
| 168 | * in frames if "useFrames" is true). For example, if the stagger value is 0.5 and the "align" | ||
| 169 | * property is set to TweenAlign.START, the second tween will start 0.5 seconds after the first one | ||
| 170 | * starts, then 0.5 seconds later the third one will start, etc. If the align property is | ||
| 171 | * TweenAlign.SEQUENCE, there would be 0.5 seconds added between each tween. This value simply gets | ||
| 172 | * passed to the insertMultiple() method. Default is 0.</li> | ||
| 173 | * | ||
| 174 | * <li><b> onStart : Function</b> A function that should be called when the timeline begins (the <code>currentProgress</code> won't necessarily | ||
| 175 | * be zero when <code>onStart</code> is called. For example, if the timeline is created and then its <code>currentProgress</code> | ||
| 176 | * property is immediately set to 0.5 or if its <code>currentTime</code> property is set to something other than zero, | ||
| 177 | * <code>onStart</code> will still get fired because it is the first time the timeline is getting rendered.)</li> | ||
| 178 | * | ||
| 179 | * <li><b> onStartParams : Array</b> An Array of parameters to pass the onStart function.</li> | ||
| 180 | * | ||
| 181 | * <li><b> onUpdate : Function</b> A function that should be called every time the timeline's time/position is updated | ||
| 182 | * (on every frame while the timeline is active)</li> | ||
| 183 | * | ||
| 184 | * <li><b> onUpdateParams : Array</b> An Array of parameters to pass the onUpdate function</li> | ||
| 185 | * | ||
| 186 | * <li><b> onComplete : Function</b> A function that should be called when the timeline has finished </li> | ||
| 187 | * | ||
| 188 | * <li><b> onCompleteParams : Array</b> An Array of parameters to pass the onComplete function</li> | ||
| 189 | * | ||
| 190 | * <li><b> onReverseComplete : Function</b> A function that should be called when the timeline has reached its starting point again after having been reversed </li> | ||
| 191 | * | ||
| 192 | * <li><b> onReverseCompleteParams : Array</b> An Array of parameters to pass the onReverseComplete functions</li> | ||
| 193 | * | ||
| 194 | * <li><b> autoRemoveChildren : Boolean</b> If autoRemoveChildren is set to true, as soon as child tweens/timelines complete, | ||
| 195 | * they will automatically get killed/removed. This is normally undesireable because | ||
| 196 | * it prevents going backwards in time (like if you want to <code>reverse()</code> or set the | ||
| 197 | * <code>currentProgress</code> value to a lower value, etc.). It can, however, improve speed and memory | ||
| 198 | * management. TweenLite's root timelines use <code>autoRemoveChildren:true</code>.</li> | ||
| 199 | * </ul> | ||
| 200 | * | ||
| 201 | * @param vars optionally pass in special properties like <code>useFrames, onComplete, onCompleteParams, onUpdate, onUpdateParams, onStart, onStartParams, tweens, align, stagger, delay, reversed,</code> and/or <code>autoRemoveChildren</code>. | ||
| 202 | */ | ||
| 203 | public function TimelineLite(vars:Object=null) { | ||
| 204 | super(vars); | ||
| 205 | _endCaps = [null, null]; | ||
| 206 | _labels = {}; | ||
| 207 | this.autoRemoveChildren = Boolean(this.vars.autoRemoveChildren == true); | ||
| 208 | _hasUpdate = Boolean(typeof(this.vars.onUpdate) == "function"); | ||
| 209 | if (this.vars.tweens is Array) { | ||
| 210 | this.insertMultiple(this.vars.tweens, 0, (this.vars.align != null) ? this.vars.align : "normal", (this.vars.stagger) ? Number(this.vars.stagger) : 0); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | /** | ||
| 215 | * @private | ||
| 216 | * Adds a TweenLite, TweenMax, TimelineLite, or TimelineMax instance to this timeline. | ||
| 217 | * Typically it is best to use the insert(), append(), or prepend() methods to add a tween | ||
| 218 | * or timeline, though. addChild() should generally be avoided (it is used primarily by other | ||
| 219 | * classes in the GreenSock tweening platform). | ||
| 220 | * | ||
| 221 | * @param tween TweenLite, TweenMax, TimelineLite, or TimelineMax instance | ||
| 222 | */ | ||
| 223 | override public function addChild(tween:TweenCore):void { | ||
| 224 | if (!tween.cachedOrphan && tween.timeline) { | ||
| 225 | tween.timeline.remove(tween, true); //removes from existing timeline so that it can be properly added to this one. Even if the timeline is this, it still needs to be removed so that it can be added in the appropriate order (required for proper rendering) | ||
| 226 | } | ||
| 227 | tween.timeline = this; | ||
| 228 | if (tween.gc) { | ||
| 229 | tween.setEnabled(true, true); | ||
| 230 | } | ||
| 231 | setDirtyCache(true); | ||
| 232 | |||
| 233 | //now make sure it is inserted in the proper order... | ||
| 234 | |||
| 235 | var first:TweenCore = (this.gc) ? _endCaps[0] : _firstChild; | ||
| 236 | var last:TweenCore = (this.gc) ? _endCaps[1] : _lastChild; | ||
| 237 | |||
| 238 | if (last == null) { | ||
| 239 | first = last = tween; | ||
| 240 | tween.nextNode = tween.prevNode = null; | ||
| 241 | } else { | ||
| 242 | var curTween:TweenCore = last, st:Number = tween.cachedStartTime; | ||
| 243 | while (curTween != null && st <= curTween.cachedStartTime) { | ||
| 244 | curTween = curTween.prevNode; | ||
| 245 | } | ||
| 246 | if (curTween == null) { | ||
| 247 | first.prevNode = tween; | ||
| 248 | tween.nextNode = first; | ||
| 249 | tween.prevNode = null; | ||
| 250 | first = tween; | ||
| 251 | } else { | ||
| 252 | if (curTween.nextNode) { | ||
| 253 | curTween.nextNode.prevNode = tween; | ||
| 254 | } else if (curTween == last) { | ||
| 255 | last = tween; | ||
| 256 | } | ||
| 257 | tween.prevNode = curTween; | ||
| 258 | tween.nextNode = curTween.nextNode; | ||
| 259 | curTween.nextNode = tween; | ||
| 260 | } | ||
| 261 | } | ||
| 262 | tween.cachedOrphan = false; | ||
| 263 | |||
| 264 | if (this.gc) { | ||
| 265 | _endCaps[0] = first; | ||
| 266 | _endCaps[1] = last; | ||
| 267 | } else { | ||
| 268 | _firstChild = first; | ||
| 269 | _lastChild = last; | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | /** | ||
| 274 | * Removes a TweenLite, TweenMax, TimelineLite, or TimelineMax instance from the timeline. | ||
| 275 | * | ||
| 276 | * @param tween TweenLite, TweenMax, TimelineLite, or TimelineMax instance to remove | ||
| 277 | * @param skipDisable If false (the default), the TweenLite/Max/TimelineLite/Max instance is disabled. This is primarily used internally - there's really no reason to set it to true. | ||
| 278 | */ | ||
| 279 | override public function remove(tween:TweenCore, skipDisable:Boolean=false):void { | ||
| 280 | if (tween.cachedOrphan) { | ||
| 281 | return; //already removed! | ||
| 282 | } else if (!skipDisable) { | ||
| 283 | tween.setEnabled(false, true); | ||
| 284 | } | ||
| 285 | |||
| 286 | var first:TweenCore = (this.gc) ? _endCaps[0] : _firstChild; | ||
| 287 | var last:TweenCore = (this.gc) ? _endCaps[1] : _lastChild; | ||
| 288 | |||
| 289 | if (tween.nextNode) { | ||
| 290 | tween.nextNode.prevNode = tween.prevNode; | ||
| 291 | } else if (last == tween) { | ||
| 292 | last = tween.prevNode; | ||
| 293 | } | ||
| 294 | if (tween.prevNode) { | ||
| 295 | tween.prevNode.nextNode = tween.nextNode; | ||
| 296 | } else if (first == tween) { | ||
| 297 | first = tween.nextNode; | ||
| 298 | } | ||
| 299 | |||
| 300 | if (this.gc) { | ||
| 301 | _endCaps[0] = first; | ||
| 302 | _endCaps[1] = last; | ||
| 303 | } else { | ||
| 304 | _firstChild = first; | ||
| 305 | _lastChild = last; | ||
| 306 | } | ||
| 307 | tween.cachedOrphan = true; | ||
| 308 | |||
| 309 | //don't null nextNode and prevNode, otherwise the chain could break in rendering loops. | ||
| 310 | setDirtyCache(true); | ||
| 311 | } | ||
| 312 | |||
| 313 | /** | ||
| 314 | * Inserts a TweenLite, TweenMax, TimelineLite, or TimelineMax instance into the timeline at a specific time, frame, or label. | ||
| 315 | * If you insert at a label that doesn't exist yet, one is created at the end of the timeline. | ||
| 316 | * | ||
| 317 | * @param tween TweenLite, TweenMax, TimelineLite, or TimelineMax instance to insert | ||
| 318 | * @param timeOrLabel The time in seconds (or frames for frames-based timelines) or label at which the tween/timeline should be inserted. For example, myTimeline.insert(myTween, 3) would insert myTween 3-seconds into the timeline, and myTimeline.insert(myTween, "myLabel") would insert it at the "myLabel" label. | ||
| 319 | */ | ||
| 320 | public function insert(tween:TweenCore, timeOrLabel:*=0):void { | ||
| 321 | if (typeof(timeOrLabel) == "string") { | ||
| 322 | if (!(timeOrLabel in _labels)) { | ||
| 323 | addLabel(timeOrLabel, this.duration); | ||
| 324 | } | ||
| 325 | timeOrLabel = Number(_labels[timeOrLabel]); | ||
| 326 | } | ||
| 327 | /* Possible addition - this would avoid situations where a TimelineLite/Max is created as a class variable and then much later the children are added to it - without this line, the timeline would never start because it would finish immediately with no tweens. | ||
| 328 | if (_firstChild == null && _endCaps[0] == null && (this.timeline == TweenLite.rootTimeline || this.timeline == TweenLite.rootFramesTimeline)) { | ||
| 329 | this.startTime = this.timeline.cachedTime; | ||
| 330 | } | ||
| 331 | */ | ||
| 332 | tween.cachedStartTime = Number(timeOrLabel) + tween.delay; | ||
| 333 | addChild(tween); | ||
| 334 | } | ||
| 335 | |||
| 336 | /** | ||
| 337 | * Inserts a TweenLite, TweenMax, TimelineLite, or TimelineMax instance at the <strong>end</strong> of the timeline, | ||
| 338 | * optionally offsetting its insertion point by a certain amount (to make it overlap with the end of | ||
| 339 | * the timeline or leave a gap before its insertion point). | ||
| 340 | * This makes it easy to build sequences by continuing to append() tweens or timelines. | ||
| 341 | * | ||
| 342 | * @param tween TweenLite, TweenMax, TimelineLite, or TimelineMax instance to append. | ||
| 343 | * @param offset Amount of seconds (or frames for frames-based timelines) to offset the insertion point of the tween from the end of the timeline. For example, to append a tween 3 seconds after the end of the timeline (leaving a 3-second gap), set the offset to 3. Or to have the tween appended so that it overlaps with the last 2 seconds of the timeline, set the offset to -2. The default is 0 so that the insertion point is exactly at the end of the timeline. | ||
| 344 | */ | ||
| 345 | public function append(tween:TweenCore, offset:Number=0):void { | ||
| 346 | insert(tween, this.duration + offset); | ||
| 347 | } | ||
| 348 | |||
| 349 | /** | ||
| 350 | * Inserts a TweenLite, TweenMax, TimelineLite, or TimelineMax instance at the beginning of the timeline, | ||
| 351 | * pushing all existing tweens back in time to make room for the newly inserted one. You can optionally | ||
| 352 | * affect the positions of labels too. | ||
| 353 | * | ||
| 354 | * @param tween TweenLite, TweenMax, TimelineLite, or TimelineMax instance to prepend | ||
| 355 | * @param adjustLabels If true, all existing labels will be adjusted back in time along with the existing tweens to keep them aligned. (default is false) | ||
| 356 | */ | ||
| 357 | public function prepend(tween:TweenCore, adjustLabels:Boolean=false):void { | ||
| 358 | shiftChildren((tween.totalDuration / tween.cachedTimeScale) + tween.delay, adjustLabels, 0); | ||
| 359 | insert(tween, 0); | ||
| 360 | } | ||
| 361 | |||
| 362 | /** | ||
| 363 | * Inserts multiple tweens/timelines into the timeline at once, optionally aligning them (as a sequence for example) | ||
| 364 | * and/or staggering the timing. This is one of the most powerful methods in TimelineLite because it accommodates | ||
| 365 | * advanced timing effects and builds complex sequences with relatively little code.<br /><br /> | ||
| 366 | * | ||
| 367 | * @param tweens an Array containing any or all of the following: TweenLite, TweenMax, TimelineLite, and/or TimelineMax instances | ||
| 368 | * @param timeOrLabel time in seconds (or frame if the timeline is frames-based) or label that serves as the point of insertion. For example, the number 2 would insert the tweens beginning at 2-seconds into the timeline, or "myLabel" would ihsert them wherever "myLabel" is. | ||
| 369 | * @param align determines how the tweens will be aligned in relation to each other before getting inserted. Options are: TweenAlign.SEQUENCE (aligns the tweens one-after-the-other in a sequence), TweenAlign.START (aligns the start times of all of the tweens (ignores delays)), and TweenAlign.NORMAL (aligns the start times of all the tweens (honors delays)). The default is NORMAL. | ||
| 370 | * @param stagger staggers the tweens by a set amount of time (in seconds) (or in frames for frames-based timelines). For example, if the stagger value is 0.5 and the "align" property is set to TweenAlign.START, the second tween will start 0.5 seconds after the first one starts, then 0.5 seconds later the third one will start, etc. If the align property is TweenAlign.SEQUENCE, there would be 0.5 seconds added between each tween. Default is 0. | ||
| 371 | */ | ||
| 372 | public function insertMultiple(tweens:Array, timeOrLabel:*=0, align:String="normal", stagger:Number=0):void { | ||
| 373 | var i:int, tween:TweenCore, curTime:Number = Number(timeOrLabel) || 0, l:uint = tweens.length; | ||
| 374 | if (typeof(timeOrLabel) == "string") { | ||
| 375 | if (!(timeOrLabel in _labels)) { | ||
| 376 | addLabel(timeOrLabel, this.duration); | ||
| 377 | } | ||
| 378 | curTime = _labels[timeOrLabel]; | ||
| 379 | } | ||
| 380 | for (i = 0; i < l; i++) { | ||
| 381 | tween = tweens[i] as TweenCore; | ||
| 382 | insert(tween, curTime); | ||
| 383 | if (align == "sequence") { | ||
| 384 | curTime = tween.cachedStartTime + (tween.totalDuration / tween.cachedTimeScale); | ||
| 385 | } else if (align == "start") { | ||
| 386 | tween.cachedStartTime -= tween.delay; | ||
| 387 | } | ||
| 388 | curTime += stagger; | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | /** | ||
| 393 | * Appends multiple tweens/timelines at the end of the timeline at once, optionally offsetting the insertion point by a certain amount, | ||
| 394 | * aligning them (as a sequence for example), and/or staggering their relative timing. This is one of the most powerful methods in | ||
| 395 | * TimelineLite because it accommodates advanced timing effects and builds complex sequences with relatively little code.<br /><br /> | ||
| 396 | * | ||
| 397 | * @param tweens an Array containing any or all of the following: TweenLite, TweenMax, TimelineLite, and/or TimelineMax instances | ||
| 398 | * @param offset Amount of seconds (or frames for frames-based timelines) to offset the insertion point of the tweens from the end of the timeline. For example, to start appending the tweens 3 seconds after the end of the timeline (leaving a 3-second gap), set the offset to 3. Or to have the tweens appended so that the insertion point overlaps with the last 2 seconds of the timeline, set the offset to -2. The default is 0 so that the insertion point is exactly at the end of the timeline. | ||
| 399 | * @param align determines how the tweens will be aligned in relation to each other before getting appended. Options are: TweenAlign.SEQUENCE (aligns the tweens one-after-the-other in a sequence), TweenAlign.START (aligns the start times of all of the tweens (ignores delays)), and TweenAlign.NORMAL (aligns the start times of all the tweens (honors delays)). The default is NORMAL. | ||
| 400 | * @param stagger staggers the tweens by a set amount of time (in seconds) (or in frames for frames-based timelines). For example, if the stagger value is 0.5 and the "align" property is set to TweenAlign.START, the second tween will start 0.5 seconds after the first one starts, then 0.5 seconds later the third one will start, etc. If the align property is TweenAlign.SEQUENCE, there would be 0.5 seconds added between each tween. Default is 0. | ||
| 401 | */ | ||
| 402 | public function appendMultiple(tweens:Array, offset:Number=0, align:String="normal", stagger:Number=0):void { | ||
| 403 | insertMultiple(tweens, this.duration + offset, align, stagger); | ||
| 404 | } | ||
| 405 | |||
| 406 | /** | ||
| 407 | * Prepends multiple tweens/timelines to the beginning of the timeline at once, moving all existing children back to make | ||
| 408 | * room, and optionally aligning the new children (as a sequence for example) and/or staggering the timing.<br /><br /> | ||
| 409 | * | ||
| 410 | * @param tweens an Array containing any or all of the following: TweenLite, TweenMax, TimelineLite, and/or TimelineMax instances | ||
| 411 | * @param align determines how the tweens will be aligned in relation to each other before getting prepended. Options are: TweenAlign.SEQUENCE (aligns the tweens one-after-the-other in a sequence), TweenAlign.START (aligns the start times of all of the tweens (ignores delays)), and TweenAlign.NORMAL (aligns the start times of all the tweens (honors delays)). The default is NORMAL. | ||
| 412 | * @param stagger staggers the tweens by a set amount of time (in seconds) (or in frames for frames-based timelines). For example, if the stagger value is 0.5 and the "align" property is set to TweenAlign.START, the second tween will start 0.5 seconds after the first one starts, then 0.5 seconds later the third one will start, etc. If the align property is TweenAlign.SEQUENCE, there would be 0.5 seconds added between each tween. Default is 0. | ||
| 413 | */ | ||
| 414 | public function prependMultiple(tweens:Array, align:String="normal", stagger:Number=0, adjustLabels:Boolean=false):void { | ||
| 415 | var tl:TimelineLite = new TimelineLite({tweens:tweens, align:align, stagger:stagger}); //dump them into a new temporary timeline initially so that we can determine the overall duration. | ||
| 416 | shiftChildren(tl.duration, adjustLabels, 0); | ||
| 417 | insertMultiple(tweens, 0, align, stagger); | ||
| 418 | tl.kill(); | ||
| 419 | } | ||
| 420 | |||
| 421 | |||
| 422 | /** | ||
| 423 | * Adds a label to the timeline, making it easy to mark important positions/times. gotoAndStop() and gotoAndPlay() | ||
| 424 | * allow you to skip directly to any label. This works just like timeline labels in the Flash IDE. | ||
| 425 | * | ||
| 426 | * @param label The name of the label | ||
| 427 | * @param time The time in seconds (or frames for frames-based timelines) at which the label should be added. For example, myTimeline.addLabel("myLabel", 3) adds the label "myLabel" at 3 seconds into the timeline. | ||
| 428 | */ | ||
| 429 | public function addLabel(label:String, time:Number):void { | ||
| 430 | _labels[label] = time; | ||
| 431 | } | ||
| 432 | |||
| 433 | /** | ||
| 434 | * Removes a label from the timeline and returns the time of that label. | ||
| 435 | * | ||
| 436 | * @param label The name of the label to remove | ||
| 437 | * @return Time associated with the label that was removed | ||
| 438 | */ | ||
| 439 | public function removeLabel(label:String):Number { | ||
| 440 | var n:Number = _labels[label]; | ||
| 441 | delete _labels[label]; | ||
| 442 | return n; | ||
| 443 | } | ||
| 444 | |||
| 445 | /** | ||
| 446 | * Returns the time associated with a particular label. If the label isn't found, -1 is returned. | ||
| 447 | * | ||
| 448 | * @param label Label name | ||
| 449 | * @return Time associated with the label (or -1 if there is no such label) | ||
| 450 | */ | ||
| 451 | public function getLabelTime(label:String):Number { | ||
| 452 | return (label in _labels) ? Number(_labels[label]) : -1; | ||
| 453 | } | ||
| 454 | |||
| 455 | /** @private **/ | ||
| 456 | protected function parseTimeOrLabel(timeOrLabel:*):Number { | ||
| 457 | if (typeof(timeOrLabel) == "string") { | ||
| 458 | if (!(timeOrLabel in _labels)) { | ||
| 459 | throw new Error("TimelineLite error: the " + timeOrLabel + " label was not found."); | ||
| 460 | return 0; | ||
| 461 | } | ||
| 462 | return getLabelTime(String(timeOrLabel)); | ||
| 463 | } | ||
| 464 | return Number(timeOrLabel); | ||
| 465 | } | ||
| 466 | |||
| 467 | /** Pauses the timeline (same as pause() - added stop() for consistency with Flash's MovieClip.stop() functionality) **/ | ||
| 468 | public function stop():void { | ||
| 469 | this.paused = true; | ||
| 470 | } | ||
| 471 | |||
| 472 | /** | ||
| 473 | * Skips to a particular time, frame, or label and plays the timeline forwards from there (unpausing it) | ||
| 474 | * | ||
| 475 | * @param timeOrLabel time in seconds (or frame if the timeline is frames-based) or label to skip to. For example, myTimeline.gotoAndPlay(2) will skip to 2-seconds into a timeline, and myTimeline.gotoAndPlay("myLabel") will skip to wherever "myLabel" is. | ||
| 476 | * @param suppressEvents If true, no events or callbacks will be triggered as the "virtual playhead" moves to the new position (onComplete, onUpdate, onReverseComplete, etc. of this timeline and any of its child tweens/timelines won't be triggered, nor will any of the associated events be dispatched) | ||
| 477 | */ | ||
| 478 | public function gotoAndPlay(timeOrLabel:*, suppressEvents:Boolean=true):void { | ||
| 479 | setTotalTime(parseTimeOrLabel(timeOrLabel), suppressEvents); | ||
| 480 | play(); | ||
| 481 | } | ||
| 482 | |||
| 483 | /** | ||
| 484 | * Skips to a particular time, frame, or label and stops the timeline (pausing it) | ||
| 485 | * | ||
| 486 | * @param timeOrLabel time in seconds (or frame if the timeline is frames-based) or label to skip to. For example, myTimeline.gotoAndStop(2) will skip to 2-seconds into a timeline, and myTimeline.gotoAndStop("myLabel") will skip to wherever "myLabel" is. | ||
| 487 | * @param suppressEvents If true, no events or callbacks will be triggered as the "virtual playhead" moves to the new position (onComplete, onUpdate, onReverseComplete, etc. of this timeline and any of its child tweens/timelines won't be triggered, nor will any of the associated events be dispatched) | ||
| 488 | */ | ||
| 489 | public function gotoAndStop(timeOrLabel:*, suppressEvents:Boolean=true):void { | ||
| 490 | setTotalTime(parseTimeOrLabel(timeOrLabel), suppressEvents); | ||
| 491 | this.paused = true; | ||
| 492 | } | ||
| 493 | |||
| 494 | /** | ||
| 495 | * Skips to a particular time, frame, or label without changing the paused state of the timeline | ||
| 496 | * | ||
| 497 | * @param timeOrLabel time in seconds (or frame if the timeline is frames-based) or label to skip to. For example, myTimeline.goto(2) will skip to 2-seconds into a timeline, and myTimeline.goto("myLabel") will skip to wherever "myLabel" is. | ||
| 498 | * @param suppressEvents If true, no events or callbacks will be triggered as the "virtual playhead" moves to the new position (onComplete, onUpdate, onReverseComplete, etc. of this timeline and any of its child tweens/timelines won't be triggered, nor will any of the associated events be dispatched) | ||
| 499 | */ | ||
| 500 | public function goto(timeOrLabel:*, suppressEvents:Boolean=true):void { | ||
| 501 | setTotalTime(parseTimeOrLabel(timeOrLabel), suppressEvents); | ||
| 502 | } | ||
| 503 | |||
| 504 | |||
| 505 | /** | ||
| 506 | * @private | ||
| 507 | * Renders all tweens and sub-timelines in the state they'd be at a particular time (or frame for frames-based timelines). | ||
| 508 | * | ||
| 509 | * @param time time in seconds (or frames for frames-based timelines) that should be rendered. | ||
| 510 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 511 | * @param force Normally the tween will skip rendering if the time matches the cachedTotalTime (to improve performance), but if force is true, it forces a render. This is primarily used internally for tweens with durations of zero in TimelineLite/Max instances. | ||
| 512 | */ | ||
| 513 | override public function renderTime(time:Number, suppressEvents:Boolean=false, force:Boolean=false):void { | ||
| 514 | if (this.gc) { | ||
| 515 | this.setEnabled(true, false); | ||
| 516 | } else if (!this.active && !this.cachedPaused) { | ||
| 517 | this.active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. | ||
| 518 | } | ||
| 519 | var totalDur:Number = (this.cacheIsDirty) ? this.totalDuration : this.cachedTotalDuration, prevTime:Number = this.cachedTime, prevStart:Number = this.cachedStartTime, prevTimeScale:Number = this.cachedTimeScale, tween:TweenCore, isComplete:Boolean, rendered:Boolean, next:TweenCore, dur:Number, prevPaused:Boolean = this.cachedPaused; | ||
| 520 | if (time >= totalDur) { | ||
| 521 | if (_rawPrevTime <= totalDur && _rawPrevTime != time) { | ||
| 522 | this.cachedTotalTime = this.cachedTime = totalDur; | ||
| 523 | forceChildrenToEnd(totalDur, suppressEvents); | ||
| 524 | isComplete = !this.hasPausedChild(); | ||
| 525 | rendered = true; | ||
| 526 | if (this.cachedDuration == 0 && isComplete && (time == 0 || _rawPrevTime < 0)) { //In order to accommodate zero-duration timelines, we must discern the momentum/direction of time in order to render values properly when the "playhead" goes past 0 in the forward direction or lands directly on it, and also when it moves past it in the backward direction (from a postitive time to a negative time). | ||
| 527 | force = true; | ||
| 528 | } | ||
| 529 | } | ||
| 530 | |||
| 531 | } else if (time <= 0) { | ||
| 532 | if (time < 0) { | ||
| 533 | this.active = false; | ||
| 534 | if (this.cachedDuration == 0 && _rawPrevTime > 0) { //In order to accommodate zero-duration timelines, we must discern the momentum/direction of time in order to render values properly when the "playhead" goes past 0 in the forward direction or lands directly on it, and also when it moves past it in the backward direction (from a postitive time to a negative time). | ||
| 535 | force = true; | ||
| 536 | isComplete = true; | ||
| 537 | } | ||
| 538 | } | ||
| 539 | if (_rawPrevTime >= 0 && _rawPrevTime != time) { | ||
| 540 | forceChildrenToBeginning(0, suppressEvents); | ||
| 541 | this.cachedTotalTime = 0; | ||
| 542 | this.cachedTime = 0; | ||
| 543 | rendered = true; | ||
| 544 | if (this.cachedReversed) { | ||
| 545 | isComplete = true; | ||
| 546 | } | ||
| 547 | } | ||
| 548 | } else { | ||
| 549 | this.cachedTotalTime = this.cachedTime = time; | ||
| 550 | } | ||
| 551 | _rawPrevTime = time; | ||
| 552 | |||
| 553 | if (this.cachedTime == prevTime && !force) { | ||
| 554 | return; | ||
| 555 | } else if (!this.initted) { | ||
| 556 | this.initted = true; | ||
| 557 | } | ||
| 558 | if (prevTime == 0 && this.vars.onStart && this.cachedTime != 0 && !suppressEvents) { | ||
| 559 | this.vars.onStart.apply(null, this.vars.onStartParams); | ||
| 560 | } | ||
| 561 | |||
| 562 | if (rendered) { | ||
| 563 | //already rendered | ||
| 564 | } else if (this.cachedTime - prevTime > 0) { | ||
| 565 | tween = _firstChild; | ||
| 566 | while (tween) { | ||
| 567 | next = tween.nextNode; //record it here because the value could change after rendering... | ||
| 568 | if (this.cachedPaused && !prevPaused) { //in case a tween pauses the timeline when rendering | ||
| 569 | break; | ||
| 570 | } else if (tween.active || (!tween.cachedPaused && tween.cachedStartTime <= this.cachedTime && !tween.gc)) { | ||
| 571 | |||
| 572 | if (!tween.cachedReversed) { | ||
| 573 | tween.renderTime((this.cachedTime - tween.cachedStartTime) * tween.cachedTimeScale, suppressEvents, false); | ||
| 574 | } else { | ||
| 575 | dur = (tween.cacheIsDirty) ? tween.totalDuration : tween.cachedTotalDuration; | ||
| 576 | tween.renderTime(dur - ((this.cachedTime - tween.cachedStartTime) * tween.cachedTimeScale), suppressEvents, false); | ||
| 577 | } | ||
| 578 | |||
| 579 | } | ||
| 580 | tween = next; | ||
| 581 | } | ||
| 582 | } else { | ||
| 583 | tween = _lastChild; | ||
| 584 | while (tween) { | ||
| 585 | next = tween.prevNode; //record it here because the value could change after rendering... | ||
| 586 | if (this.cachedPaused && !prevPaused) { //in case a tween pauses the timeline when rendering | ||
| 587 | break; | ||
| 588 | } else if (tween.active || (!tween.cachedPaused && tween.cachedStartTime <= prevTime && !tween.gc)) { | ||
| 589 | |||
| 590 | if (!tween.cachedReversed) { | ||
| 591 | tween.renderTime((this.cachedTime - tween.cachedStartTime) * tween.cachedTimeScale, suppressEvents, false); | ||
| 592 | } else { | ||
| 593 | dur = (tween.cacheIsDirty) ? tween.totalDuration : tween.cachedTotalDuration; | ||
| 594 | tween.renderTime(dur - ((this.cachedTime - tween.cachedStartTime) * tween.cachedTimeScale), suppressEvents, false); | ||
| 595 | } | ||
| 596 | |||
| 597 | } | ||
| 598 | tween = next; | ||
| 599 | } | ||
| 600 | } | ||
| 601 | if (_hasUpdate && !suppressEvents) { | ||
| 602 | this.vars.onUpdate.apply(null, this.vars.onUpdateParams); | ||
| 603 | } | ||
| 604 | if (isComplete && (prevStart == this.cachedStartTime || prevTimeScale != this.cachedTimeScale) && (totalDur >= this.totalDuration || this.cachedTime == 0)) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), we shouldn't run complete() because it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would have called complete() if it was necessary at the new time. The only exception is the timeScale property. | ||
| 605 | complete(true, suppressEvents); | ||
| 606 | } | ||
| 607 | } | ||
| 608 | |||
| 609 | /** | ||
| 610 | * @private | ||
| 611 | * Due to occassional floating point rounding errors in Flash, sometimes child tweens/timelines were not being | ||
| 612 | * rendered at the very beginning (their currentProgress might be 0.000000000001 instead of 0 because when Flash | ||
| 613 | * performed this.cachedTime - tween.startTime, floating point errors would return a value that | ||
| 614 | * was SLIGHTLY off). This method forces them to the beginning. | ||
| 615 | * | ||
| 616 | * @param time Time that should be rendered (either zero or a negative number). The reason a negative number could be important is because if there are zero-duration tweens at the very beginning (startTime=0), we need a way to sense when the timeline has gone backwards BEYOND zero so that the tweens know to render their starting values instead of their ending values. If the time is exactly zero, those tweens would render their end values. | ||
| 617 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 618 | */ | ||
| 619 | protected function forceChildrenToBeginning(time:Number, suppressEvents:Boolean=false):Number { | ||
| 620 | var tween:TweenCore = _lastChild, next:TweenCore, dur:Number; | ||
| 621 | var prevPaused:Boolean = this.cachedPaused; | ||
| 622 | while (tween) { | ||
| 623 | next = tween.prevNode; //record it here because the value could change after rendering... | ||
| 624 | if (this.cachedPaused && !prevPaused) { //in case a tween pauses the timeline when rendering | ||
| 625 | break; | ||
| 626 | } else if (tween.active || (!tween.cachedPaused && !tween.gc && (tween.cachedTotalTime != 0 || tween.cachedDuration == 0))) { | ||
| 627 | |||
| 628 | if (time == 0 && (tween.cachedDuration != 0 || tween.cachedStartTime == 0)) { | ||
| 629 | tween.renderTime(tween.cachedReversed ? tween.cachedTotalDuration : 0, suppressEvents, false); | ||
| 630 | } else if (!tween.cachedReversed) { | ||
| 631 | tween.renderTime((time - tween.cachedStartTime) * tween.cachedTimeScale, suppressEvents, false); | ||
| 632 | } else { | ||
| 633 | dur = (tween.cacheIsDirty) ? tween.totalDuration : tween.cachedTotalDuration; | ||
| 634 | tween.renderTime(dur - ((time - tween.cachedStartTime) * tween.cachedTimeScale), suppressEvents, false); | ||
| 635 | } | ||
| 636 | |||
| 637 | } | ||
| 638 | tween = next; | ||
| 639 | } | ||
| 640 | return time; | ||
| 641 | } | ||
| 642 | |||
| 643 | /** | ||
| 644 | * @private | ||
| 645 | * Due to occassional floating point rounding errors in Flash, sometimes child tweens/timelines were not being | ||
| 646 | * fully completed (their currentProgress might be 0.999999999999998 instead of 1 because when Flash | ||
| 647 | * performed this.cachedTime - tween.startTime, floating point errors would return a value that | ||
| 648 | * was SLIGHTLY off). This method forces them to completion. | ||
| 649 | * | ||
| 650 | * @param time Time that should be rendered (either this.totalDuration or greater). The reason a greater number could be important is because if there are reversed zero-duration tweens at the very end, we need a way to sense when the timeline has gone BEYOND the end so that the tweens know to render their starting values instead of their ending values. If the time is exactly this.totalDuration, those reversed zero-duration tweens would render their end values. | ||
| 651 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 652 | */ | ||
| 653 | protected function forceChildrenToEnd(time:Number, suppressEvents:Boolean=false):Number { | ||
| 654 | var tween:TweenCore = _firstChild, next:TweenCore, dur:Number; | ||
| 655 | var prevPaused:Boolean = this.cachedPaused; | ||
| 656 | while (tween) { | ||
| 657 | next = tween.nextNode; //record it here because the value could change after rendering... | ||
| 658 | if (this.cachedPaused && !prevPaused) { //in case a tween pauses the timeline when rendering | ||
| 659 | break; | ||
| 660 | } else if (tween.active || (!tween.cachedPaused && !tween.gc && (tween.cachedTotalTime != tween.cachedTotalDuration || tween.cachedDuration == 0))) { | ||
| 661 | |||
| 662 | if (time == this.cachedDuration && (tween.cachedDuration != 0 || tween.cachedStartTime == this.cachedDuration)) { | ||
| 663 | tween.renderTime(tween.cachedReversed ? 0 : tween.cachedTotalDuration, suppressEvents, false); | ||
| 664 | } else if (!tween.cachedReversed) { | ||
| 665 | tween.renderTime((time - tween.cachedStartTime) * tween.cachedTimeScale, suppressEvents, false); | ||
| 666 | } else { | ||
| 667 | dur = (tween.cacheIsDirty) ? tween.totalDuration : tween.cachedTotalDuration; | ||
| 668 | tween.renderTime(dur - ((time - tween.cachedStartTime) * tween.cachedTimeScale), suppressEvents, false); | ||
| 669 | } | ||
| 670 | |||
| 671 | } | ||
| 672 | tween = next; | ||
| 673 | } | ||
| 674 | return time; | ||
| 675 | } | ||
| 676 | |||
| 677 | /** | ||
| 678 | * @private | ||
| 679 | * Checks the timeline to see if it has any paused children (tweens/timelines). | ||
| 680 | * | ||
| 681 | * @return Indicates whether or not the timeline contains any paused children | ||
| 682 | */ | ||
| 683 | public function hasPausedChild():Boolean { | ||
| 684 | var tween:TweenCore = (this.gc) ? _endCaps[0] : _firstChild; | ||
| 685 | while (tween) { | ||
| 686 | if (tween.cachedPaused || ((tween is TimelineLite) && (tween as TimelineLite).hasPausedChild())) { | ||
| 687 | return true; | ||
| 688 | } | ||
| 689 | tween = tween.nextNode; | ||
| 690 | } | ||
| 691 | return false; | ||
| 692 | } | ||
| 693 | |||
| 694 | /** | ||
| 695 | * Provides an easy way to get all of the tweens and/or timelines nested in this timeline (as an Array). | ||
| 696 | * | ||
| 697 | * @param nested determines whether or not tweens and/or timelines that are inside nested timelines should be returned. If you only want the "top level" tweens/timelines, set this to false. | ||
| 698 | * @param tweens determines whether or not tweens (TweenLite and TweenMax instances) should be included in the results | ||
| 699 | * @param timelines determines whether or not timelines (TimelineLite and TimelineMax instances) should be included in the results | ||
| 700 | * @param ignoreBeforeTime All children with start times that are less than this value will be ignored. | ||
| 701 | * @return an Array containing the child tweens/timelines. | ||
| 702 | */ | ||
| 703 | public function getChildren(nested:Boolean=true, tweens:Boolean=true, timelines:Boolean=true, ignoreBeforeTime:Number=-9999999999):Array { | ||
| 704 | var a:Array = [], cnt:uint = 0, tween:TweenCore = (this.gc) ? _endCaps[0] : _firstChild; | ||
| 705 | while (tween) { | ||
| 706 | if (tween.cachedStartTime < ignoreBeforeTime) { | ||
| 707 | //do nothing | ||
| 708 | } else if (tween is TweenLite) { | ||
| 709 | if (tweens) { | ||
| 710 | a[cnt++] = tween; | ||
| 711 | } | ||
| 712 | } else { | ||
| 713 | if (timelines) { | ||
| 714 | a[cnt++] = tween; | ||
| 715 | } | ||
| 716 | if (nested) { | ||
| 717 | a = a.concat(TimelineLite(tween).getChildren(true, tweens, timelines)); | ||
| 718 | } | ||
| 719 | } | ||
| 720 | tween = tween.nextNode; | ||
| 721 | } | ||
| 722 | return a; | ||
| 723 | } | ||
| 724 | |||
| 725 | /** | ||
| 726 | * Returns the tweens of a particular object that are inside this timeline. | ||
| 727 | * | ||
| 728 | * @param target the target object of the tweens | ||
| 729 | * @param nested determines whether or not tweens that are inside nested timelines should be returned. If you only want the "top level" tweens/timelines, set this to false. | ||
| 730 | * @return an Array of TweenLite and TweenMax instances | ||
| 731 | */ | ||
| 732 | public function getTweensOf(target:Object, nested:Boolean=true):Array { | ||
| 733 | var tweens:Array = getChildren(nested, true, false), a:Array = [], i:int; | ||
| 734 | var l:uint = tweens.length; | ||
| 735 | var cnt:uint = 0; | ||
| 736 | for (i = 0; i < l; i++) { | ||
| 737 | if (TweenLite(tweens[i]).target == target) { | ||
| 738 | a[cnt++] = tweens[i]; | ||
| 739 | } | ||
| 740 | } | ||
| 741 | return a; | ||
| 742 | } | ||
| 743 | |||
| 744 | /** | ||
| 745 | * Shifts the startTime of the timeline's children by a certain amount and optionally adjusts labels too. This can be useful | ||
| 746 | * when you want to prepend children or splice them into a certain spot, moving existing ones back to make room for the new ones. | ||
| 747 | * | ||
| 748 | * @param amount Number of seconds (or frames for frames-based timelines) to move each child. | ||
| 749 | * @param adjustLabels If true, the timing of all labels will be adjusted as well. | ||
| 750 | * @param ignoreBeforeTime All children that begin at or after the startAtTime will be affected by the shift (the default is 0, causing all children to be affected). This provides an easy way to splice children into a certain spot on the timeline, pushing only the children after that point back to make room. | ||
| 751 | */ | ||
| 752 | public function shiftChildren(amount:Number, adjustLabels:Boolean=false, ignoreBeforeTime:Number=0):void { | ||
| 753 | var tween:TweenCore = (this.gc) ? _endCaps[0] : _firstChild; | ||
| 754 | while (tween) { | ||
| 755 | if (tween.cachedStartTime >= ignoreBeforeTime) { | ||
| 756 | tween.cachedStartTime += amount; | ||
| 757 | } | ||
| 758 | tween = tween.nextNode; | ||
| 759 | } | ||
| 760 | if (adjustLabels) { | ||
| 761 | for (var p:String in _labels) { | ||
| 762 | if (_labels[p] >= ignoreBeforeTime) { | ||
| 763 | _labels[p] += amount; | ||
| 764 | } | ||
| 765 | } | ||
| 766 | } | ||
| 767 | this.setDirtyCache(true); | ||
| 768 | } | ||
| 769 | |||
| 770 | /** | ||
| 771 | * Kills all the tweens (or certain tweening properties) of a particular object inside this TimelineLite, | ||
| 772 | * optionally completing them first. If, for example, you want to kill all tweens of the "mc" object, you'd do:<br /><br /><code> | ||
| 773 | * | ||
| 774 | * myTimeline.killTweensOf(mc);<br /><br /></code> | ||
| 775 | * | ||
| 776 | * But if you only want to kill all the "alpha" and "x" portions of mc's tweens, you'd do:<br /><br /><code> | ||
| 777 | * | ||
| 778 | * myTimeline.killTweensOf(mc, false, {alpha:true, x:true});<br /><br /></code> | ||
| 779 | * | ||
| 780 | * Killing a tween also removes it from the timeline. | ||
| 781 | * | ||
| 782 | * @param target the target object of the tweens | ||
| 783 | * @param nested determines whether or not tweens that are inside nested timelines should be affected. If you only want the "top level" tweens/timelines to be affected, set this to false. | ||
| 784 | * @param vars An object defining which tweening properties should be killed (null causes all properties to be killed). For example, if you only want to kill "alpha" and "x" tweens of object "mc", you'd do <code>myTimeline.killTweensOf(mc, true, {alpha:true, x:true})</code>. If there are no tweening properties remaining in a tween after the indicated properties are killed, the entire tween is killed, meaning any onComplete, onUpdate, onStart, etc. won't fire. | ||
| 785 | */ | ||
| 786 | public function killTweensOf(target:Object, nested:Boolean=true, vars:Object=null):Boolean { | ||
| 787 | var tweens:Array = getTweensOf(target, nested); | ||
| 788 | var i:int = tweens.length; | ||
| 789 | var tween:TweenLite; | ||
| 790 | while (--i > -1) { | ||
| 791 | tween = tweens[i]; | ||
| 792 | if (vars != null) { | ||
| 793 | tween.killVars(vars); | ||
| 794 | } | ||
| 795 | if (vars == null || (tween.cachedPT1 == null && tween.initted)) { | ||
| 796 | tween.setEnabled(false, false); | ||
| 797 | } | ||
| 798 | } | ||
| 799 | return Boolean(tweens.length > 0); | ||
| 800 | } | ||
| 801 | |||
| 802 | /** @inheritDoc **/ | ||
| 803 | override public function invalidate():void { | ||
| 804 | var tween:TweenCore = (this.gc) ? _endCaps[0] : _firstChild; | ||
| 805 | while (tween) { | ||
| 806 | tween.invalidate(); | ||
| 807 | tween = tween.nextNode; | ||
| 808 | } | ||
| 809 | } | ||
| 810 | |||
| 811 | /** | ||
| 812 | * Empties the timeline of all child tweens/timelines, or you can optionally pass an Array containing specific | ||
| 813 | * tweens/timelines to remove. So <code>myTimeline.clear()</code> would remove all children whereas | ||
| 814 | * <code>myTimeline.clear([tween1, tween2])</code> would only remove tween1 and tween2. You could even clear only | ||
| 815 | * the tweens of a particular object with <code>myTimeline.clear(myTimeline.getTweensOf(myObject));</code> | ||
| 816 | * | ||
| 817 | * @param tweens (optional) An Array containing specific children to remove. | ||
| 818 | */ | ||
| 819 | public function clear(tweens:Array=null):void { | ||
| 820 | if (tweens == null) { | ||
| 821 | tweens = getChildren(false, true, true); | ||
| 822 | } | ||
| 823 | var i:int = tweens.length; | ||
| 824 | while (--i > -1) { | ||
| 825 | TweenCore(tweens[i]).setEnabled(false, false); | ||
| 826 | } | ||
| 827 | } | ||
| 828 | |||
| 829 | /** @private **/ | ||
| 830 | override public function setEnabled(enabled:Boolean, ignoreTimeline:Boolean=false):Boolean { | ||
| 831 | if (enabled == this.gc) { | ||
| 832 | var tween:TweenCore, next:TweenCore; | ||
| 833 | /* | ||
| 834 | NOTE: To avoid circular references (TweenCore.timeline and SimpleTimeline._firstChild/_lastChild) which cause garbage collection | ||
| 835 | problems, store the _firstChild and _lastChild in the _endCaps Array when the timeline is disabled. | ||
| 836 | */ | ||
| 837 | |||
| 838 | if (enabled) { | ||
| 839 | _firstChild = tween = _endCaps[0]; | ||
| 840 | _lastChild = _endCaps[1]; | ||
| 841 | _endCaps = [null, null]; | ||
| 842 | } else { | ||
| 843 | tween = _firstChild; | ||
| 844 | _endCaps = [_firstChild, _lastChild]; | ||
| 845 | _firstChild = _lastChild = null; | ||
| 846 | } | ||
| 847 | |||
| 848 | while (tween) { | ||
| 849 | tween.setEnabled(enabled, true); | ||
| 850 | tween = tween.nextNode; | ||
| 851 | } | ||
| 852 | } | ||
| 853 | return super.setEnabled(enabled, ignoreTimeline); | ||
| 854 | } | ||
| 855 | |||
| 856 | |||
| 857 | //---- GETTERS / SETTERS ------------------------------------------------------------------------------------------------------- | ||
| 858 | |||
| 859 | /** | ||
| 860 | * Value between 0 and 1 indicating the progress of the timeline according to its duration | ||
| 861 | * where 0 is at the beginning, 0.5 is halfway finished, and 1 is finished. <code>totalProgress</code>, | ||
| 862 | * by contrast, describes the overall progress according to the timeline's <code>totalDuration</code> | ||
| 863 | * which includes repeats and repeatDelays (if there are any). Since TimelineLite doesn't offer | ||
| 864 | * "repeat" and "repeatDelay" functionality, <code>currentProgress</code> and <code>totalProgress</code> are always the same | ||
| 865 | * but in TimelineMax, they could be different. For example, if a TimelineMax instance | ||
| 866 | * is set to repeat once, at the end of the first cycle <code>totalProgress</code> would only be 0.5 | ||
| 867 | * whereas <code>currentProgress</code> would be 1. If you tracked both properties over the course of the | ||
| 868 | * tween, you'd see <code>currentProgress</code> go from 0 to 1 twice (once for each cycle) in the same | ||
| 869 | * time it takes the <code>totalProgress</code> property to go from 0 to 1 once. | ||
| 870 | **/ | ||
| 871 | public function get currentProgress():Number { | ||
| 872 | return this.cachedTime / this.duration; | ||
| 873 | } | ||
| 874 | |||
| 875 | public function set currentProgress(n:Number):void { | ||
| 876 | setTotalTime(this.duration * n, false); | ||
| 877 | } | ||
| 878 | |||
| 879 | /** | ||
| 880 | * Duration of the timeline in seconds (or frames for frames-based timelines) not including any repeats | ||
| 881 | * or repeatDelays. <code>totalDuration</code>, by contrast, does include repeats and repeatDelays but since TimelineLite | ||
| 882 | * doesn't offer "repeat" and "repeatDelay" functionality, <code>duration</code> and <code>totalDuration</code> will always be the same. | ||
| 883 | * In TimelineMax, however, they could be different. | ||
| 884 | **/ | ||
| 885 | override public function get duration():Number { | ||
| 886 | if (this.cacheIsDirty) { | ||
| 887 | var d:Number = this.totalDuration; //just triggers recalculation | ||
| 888 | } | ||
| 889 | return this.cachedDuration; | ||
| 890 | } | ||
| 891 | |||
| 892 | override public function set duration(n:Number):void { | ||
| 893 | if (this.duration != 0 && n != 0) { | ||
| 894 | this.timeScale = this.duration / n; | ||
| 895 | } | ||
| 896 | } | ||
| 897 | |||
| 898 | /** | ||
| 899 | * Duration of the timeline in seconds (or frames for frames-based timelines) including any repeats | ||
| 900 | * or repeatDelays. <code>duration</code>, by contrast, does NOT include repeats and repeatDelays. Since TimelineLite | ||
| 901 | * doesn't offer "repeat" and "repeatDelay" functionality, <code>duration</code> and <code>totalDuration</code> will always be the same. | ||
| 902 | * In TimelineMax, however, they could be different. | ||
| 903 | **/ | ||
| 904 | override public function get totalDuration():Number { | ||
| 905 | if (this.cacheIsDirty) { | ||
| 906 | var max:Number = 0, end:Number, tween:TweenCore = (this.gc) ? _endCaps[0] : _firstChild, prevStart:Number = -Infinity, next:TweenCore; | ||
| 907 | while (tween) { | ||
| 908 | next = tween.nextNode; //record it here in case the tween changes position in the sequence... | ||
| 909 | |||
| 910 | if (tween.cachedStartTime < prevStart) { //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence | ||
| 911 | this.addChild(tween); | ||
| 912 | prevStart = tween.prevNode.cachedStartTime; | ||
| 913 | } else { | ||
| 914 | prevStart = tween.cachedStartTime; | ||
| 915 | } | ||
| 916 | if (tween.cachedStartTime < 0) { //children aren't allowed to have negative startTimes, so adjust here if one is found. | ||
| 917 | max -= tween.cachedStartTime; | ||
| 918 | this.shiftChildren(-tween.cachedStartTime, false, -9999999999); | ||
| 919 | } | ||
| 920 | end = tween.cachedStartTime + (tween.totalDuration / tween.cachedTimeScale); | ||
| 921 | if (end > max) { | ||
| 922 | max = end; | ||
| 923 | } | ||
| 924 | |||
| 925 | tween = next; | ||
| 926 | } | ||
| 927 | this.cachedDuration = this.cachedTotalDuration = max; | ||
| 928 | this.cacheIsDirty = false; | ||
| 929 | } | ||
| 930 | return this.cachedTotalDuration; | ||
| 931 | } | ||
| 932 | |||
| 933 | override public function set totalDuration(n:Number):void { | ||
| 934 | if (this.totalDuration != 0 && n != 0) { | ||
| 935 | this.timeScale = this.totalDuration / n; | ||
| 936 | } | ||
| 937 | } | ||
| 938 | |||
| 939 | /** Multiplier describing the speed of the timeline where 1 is normal speed, 0.5 is half-speed, 2 is double speed, etc. **/ | ||
| 940 | public function get timeScale():Number { | ||
| 941 | return this.cachedTimeScale; | ||
| 942 | } | ||
| 943 | |||
| 944 | public function set timeScale(n:Number):void { | ||
| 945 | if (n == 0) { //can't allow zero because it'll throw the math off | ||
| 946 | n = 0.0001; | ||
| 947 | } | ||
| 948 | var tlTime:Number = (_pauseTime || _pauseTime == 0) ? _pauseTime : this.timeline.cachedTotalTime; | ||
| 949 | this.cachedStartTime = tlTime - ((tlTime - this.cachedStartTime) * this.cachedTimeScale / n); | ||
| 950 | this.cachedTimeScale = n; | ||
| 951 | setDirtyCache(false); | ||
| 952 | } | ||
| 953 | |||
| 954 | /** | ||
| 955 | * Indicates whether or not the timeline's timing mode is frames-based as opposed to time-based. | ||
| 956 | * This can only be set via the vars object in the constructor, or by attaching it to a timeline with the desired | ||
| 957 | * timing mode (a timeline's timing mode is always determined by its parent timeline) | ||
| 958 | **/ | ||
| 959 | public function get useFrames():Boolean { | ||
| 960 | var tl:SimpleTimeline = this.timeline; | ||
| 961 | while (tl.timeline) { | ||
| 962 | tl = tl.timeline; | ||
| 963 | } | ||
| 964 | return Boolean(tl == TweenLite.rootFramesTimeline); | ||
| 965 | } | ||
| 966 | |||
| 967 | /** | ||
| 968 | * @private | ||
| 969 | * Reports the totalTime of the timeline without capping the number at the totalDuration (max) and zero (minimum) which can be useful when | ||
| 970 | * unpausing tweens/timelines. Imagine a case where a paused tween is in a timeline that has already reached the end, but then | ||
| 971 | * the tween gets unpaused - it needs a way to place itself accurately in time AFTER what was previously the timeline's end time. | ||
| 972 | * | ||
| 973 | * @return The totalTime of the timeline without capping the number at the totalDuration (max) and zero (minimum) | ||
| 974 | */ | ||
| 975 | override public function get rawTime():Number { | ||
| 976 | if ((this.cachedTotalTime != 0 && this.cachedTotalTime != this.cachedTotalDuration)) { //note: don't use this.totalDuration because if other tweens get unpaused before this one, the totalDuration could change. | ||
| 977 | return this.cachedTotalTime; | ||
| 978 | } else { | ||
| 979 | return (this.timeline.rawTime - this.cachedStartTime) * this.cachedTimeScale; | ||
| 980 | } | ||
| 981 | } | ||
| 982 | |||
| 983 | |||
| 984 | } | ||
| 985 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.381 | ||
| 3 | * DATE: 2010-05-17 | ||
| 4 | * AS3 (AS2 version is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.greensock.com/timelinemax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock { | ||
| 8 | import com.greensock.core.*; | ||
| 9 | import com.greensock.events.TweenEvent; | ||
| 10 | |||
| 11 | import flash.events.*; | ||
| 12 | import flash.utils.*; | ||
| 13 | /** | ||
| 14 | * TimelineMax extends TimelineLite, offering exactly the same functionality plus useful | ||
| 15 | * (but non-essential) features like AS3 event dispatching, repeat, repeatDelay, yoyo, | ||
| 16 | * currentLabel, addCallback(), removeCallback(), tweenTo(), tweenFromTo(), getLabelAfter(), getLabelBefore(), | ||
| 17 | * and getActive() (and probably more in the future). It is the ultimate sequencing tool. | ||
| 18 | * Think of a TimelineMax instance like a virtual MovieClip timeline or a container where | ||
| 19 | * you place tweens (or other timelines) over the course of time. You can: | ||
| 20 | * | ||
| 21 | * <ul> | ||
| 22 | * <li> build sequences easily by adding tweens with the append(), prepend(), insert(), appendMultiple(), | ||
| 23 | * prependMultiple(), and insertMultiple() methods. Tweens can overlap as much as you want and you have | ||
| 24 | * complete control over where they get placed on the timeline.</li> | ||
| 25 | * | ||
| 26 | * <li> add labels, play(), stop(), gotoAndPlay(), gotoAndStop(), restart(), tweenTo() and even reverse()! </li> | ||
| 27 | * | ||
| 28 | * <li> nest timelines within timelines as deeply as you want.</li> | ||
| 29 | * | ||
| 30 | * <li> set the progress of the timeline using its <code>currentProgress</code> property. For example, to skip to | ||
| 31 | * the halfway point, set <code>myTimeline.currentProgress = 0.5</code>.</li> | ||
| 32 | * | ||
| 33 | * <li> tween the <code>currentTime</code>, <code>totalTime</code>, <code>currentProgress</code>, or <code>totalProgress</code> | ||
| 34 | * property to fastforward/rewind the timeline. You could | ||
| 35 | * even attach a slider to one of these properties to give the user the ability to drag | ||
| 36 | * forwards/backwards through the whole timeline.</li> | ||
| 37 | * | ||
| 38 | * <li> add onStart, onUpdate, onComplete, onReverseComplete, and/or onRepeat callbacks using the | ||
| 39 | * constructor's <code>vars</code> object.</li> | ||
| 40 | * | ||
| 41 | * <li> speed up or slow down the entire timeline with its <code>timeScale</code> property. You can even tween | ||
| 42 | * this property to gradually speed up or slow down the timeline.</li> | ||
| 43 | * | ||
| 44 | * <li> use the insertMultiple(), appendMultiple(), or prependMultiple() methods to create | ||
| 45 | * complex sequences including various alignment modes and staggering capabilities. | ||
| 46 | * Works great in conjunction with TweenMax.allTo() too. </li> | ||
| 47 | * | ||
| 48 | * <li> base the timing on frames instead of seconds if you prefer. Please note, however, that | ||
| 49 | * the timeline's timing mode dictates its childrens' timing mode as well. </li> | ||
| 50 | * | ||
| 51 | * <li> kill the tweens of a particular object inside the timeline with killTweensOf() or get the tweens of an object | ||
| 52 | * with getTweensOf() or get all the tweens/timelines in the timeline with getChildren()</li> | ||
| 53 | * | ||
| 54 | * <li> set the timeline to repeat any number of times or indefinitely. You can even set a delay | ||
| 55 | * between each repeat cycle and/or cause the repeat cycles to yoyo, appearing to reverse | ||
| 56 | * every other cycle. </li> | ||
| 57 | * | ||
| 58 | * <li> listen for START, UPDATE, REPEAT, REVERSE_COMPLETE, and COMPLETE events.</li> | ||
| 59 | * | ||
| 60 | * <li> get the active tweens in the timeline with getActive().</li> | ||
| 61 | * | ||
| 62 | * <li> add callbacks (function calls) anywhere in the timeline that call a function of your choosing when | ||
| 63 | * the "virtual playhead" passes a particular spot.</li> | ||
| 64 | * | ||
| 65 | * <li> Get the <code>currentLabel</code> or find labels at various positions in the timeline | ||
| 66 | * using getLabelAfter() and getLabelBefore()</li> | ||
| 67 | * </ul> | ||
| 68 | * | ||
| 69 | * <b>EXAMPLE:</b><br /><br /><code> | ||
| 70 | * | ||
| 71 | * import com.greensock.~~;<br /><br /> | ||
| 72 | * | ||
| 73 | * //create the timeline and add an onComplete call to myFunction when the timeline completes<br /> | ||
| 74 | * var myTimeline:TimelineMax = new TimelineMax({onComplete:myFunction});<br /><br /> | ||
| 75 | * | ||
| 76 | * //add a tween<br /> | ||
| 77 | * myTimeline.append(new TweenLite(mc, 1, {x:200, y:100}));<br /><br /> | ||
| 78 | * | ||
| 79 | * //add another tween at the end of the timeline (makes sequencing easy)<br /> | ||
| 80 | * myTimeline.append(new TweenLite(mc, 0.5, {alpha:0}));<br /><br /> | ||
| 81 | * | ||
| 82 | * //repeat the entire timeline twice<br /> | ||
| 83 | * myTimeline.repeat = 2;<br /><br /> | ||
| 84 | * | ||
| 85 | * //delay the repeat by 0.5 seconds each time.<br /> | ||
| 86 | * myTimeline.repeatDelay = 0.5;<br /><br /> | ||
| 87 | * | ||
| 88 | * //pause the timeline (stop() works too)<br /> | ||
| 89 | * myTimeline.pause();<br /><br /> | ||
| 90 | * | ||
| 91 | * //reverse it anytime...<br /> | ||
| 92 | * myTimeline.reverse();<br /><br /> | ||
| 93 | * | ||
| 94 | * //Add a "spin" label 3-seconds into the timeline.<br /> | ||
| 95 | * myTimeline.addLabel("spin", 3);<br /><br /> | ||
| 96 | * | ||
| 97 | * //insert a rotation tween at the "spin" label (you could also define the insert point as the time instead of a label)<br /> | ||
| 98 | * myTimeline.insert(new TweenLite(mc, 2, {rotation:"360"}), "spin"); <br /><br /> | ||
| 99 | * | ||
| 100 | * //go to the "spin" label and play the timeline from there...<br /> | ||
| 101 | * myTimeline.gotoAndPlay("spin");<br /><br /> | ||
| 102 | * | ||
| 103 | * //call myCallbackwhen the "virtual playhead" travels past the 1.5-second point. | ||
| 104 | * myTimeline.addCallback(myCallback, 1.5); | ||
| 105 | * | ||
| 106 | * //add a tween to the beginning of the timeline, pushing all the other existing tweens back in time<br /> | ||
| 107 | * myTimeline.prepend(new TweenMax(mc, 1, {tint:0xFF0000}));<br /><br /> | ||
| 108 | * | ||
| 109 | * //nest another TimelineMax inside your timeline...<br /> | ||
| 110 | * var nestedTimeline:TimelineMax = new TimelineMax();<br /> | ||
| 111 | * nestedTimeline.append(new TweenLite(mc2, 1, {x:200}));<br /> | ||
| 112 | * myTimeline.append(nestedTimeline);<br /><br /></code> | ||
| 113 | * | ||
| 114 | * | ||
| 115 | * <code>insertMultiple()</code> and <code>appendMultiple()</code> provide some very powerful sequencing tools as well, | ||
| 116 | * allowing you to add an Array of tweens/timelines and optionally align them with <code>SEQUENCE</code> or <code>START</code> | ||
| 117 | * modes, and even stagger them if you want. For example, to insert 3 tweens into the timeline, aligning their start times but | ||
| 118 | * staggering them by 0.2 seconds, <br /><br /><code> | ||
| 119 | * | ||
| 120 | * myTimeline.insertMultiple([new TweenLite(mc, 1, {y:"100"}), | ||
| 121 | * new TweenLite(mc2, 1, {x:120}), | ||
| 122 | * new TweenLite(mc3, 1, {alpha:0.5})], | ||
| 123 | * 0, | ||
| 124 | * TweenAlign.START, | ||
| 125 | * 0.2);</code><br /><br /> | ||
| 126 | * | ||
| 127 | * You can use the constructor's <code>vars</code> object to do all the setup too, like:<br /><br /><code> | ||
| 128 | * | ||
| 129 | * var myTimeline:TimelineMax = new TimelineMax({tweens:[new TweenLite(mc1, 1, {y:"100"}), TweenMax.to(mc2, 1, {tint:0xFF0000})], align:TweenAlign.SEQUENCE, onComplete:myFunction, repeat:2, repeatDelay:1});</code><br /><br /> | ||
| 130 | * | ||
| 131 | * If that confuses you, don't worry. Just use the <code>append()</code>, <code>insert()</code>, and <code>prepend()</code> methods to build your | ||
| 132 | * sequence. But power users will likely appreciate the quick, compact way they can set up sequences now. <br /><br /> | ||
| 133 | * | ||
| 134 | * | ||
| 135 | * <b>NOTES:</b> | ||
| 136 | * <ul> | ||
| 137 | * <li> TimelineMax automatically inits the OverwriteManager class to prevent unexpected overwriting behavior in sequences. | ||
| 138 | * The default mode is <code>AUTO</code>, but you can set it to whatever you want with <code>OverwriteManager.init()</code> | ||
| 139 | * (see <a href="http://www.greensock.com/overwritemanager/">http://www.greensock.com/overwritemanager/</a>)</li> | ||
| 140 | * <li> TimelineMax adds about 4.9k to your SWF (not including OverwriteManager).</li> | ||
| 141 | * </ul> | ||
| 142 | * | ||
| 143 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 144 | * | ||
| 145 | * @author Jack Doyle, jack@greensock.com | ||
| 146 | **/ | ||
| 147 | public class TimelineMax extends TimelineLite implements IEventDispatcher { | ||
| 148 | /** @private **/ | ||
| 149 | public static const version:Number = 1.381; | ||
| 150 | |||
| 151 | /** @private **/ | ||
| 152 | protected var _repeat:int; | ||
| 153 | /** @private **/ | ||
| 154 | protected var _repeatDelay:Number; | ||
| 155 | /** @private **/ | ||
| 156 | protected var _cyclesComplete:uint; | ||
| 157 | /** @private **/ | ||
| 158 | protected var _dispatcher:EventDispatcher; | ||
| 159 | /** @private **/ | ||
| 160 | protected var _hasUpdateListener:Boolean; | ||
| 161 | |||
| 162 | /** | ||
| 163 | * Works in conjunction with the repeat property, determining the behavior of each cycle; when <code>yoyo</code> is true, | ||
| 164 | * the timeline will go back and forth, appearing to reverse every other cycle (this has no affect on the <code>reversed</code> property though). | ||
| 165 | * So if repeat is 2 and <code>yoyo</code> is false, it will look like: start - 1 - 2 - 3 - 1 - 2 - 3 - 1 - 2 - 3 - end. | ||
| 166 | * But if repeat is 2 and <code>yoyo</code> is true, it will look like: start - 1 - 2 - 3 - 3 - 2 - 1 - 1 - 2 - 3 - end. | ||
| 167 | **/ | ||
| 168 | public var yoyo:Boolean; | ||
| 169 | |||
| 170 | /** | ||
| 171 | * Constructor. <br /><br /> | ||
| 172 | * | ||
| 173 | * <b>SPECIAL PROPERTIES</b><br /> | ||
| 174 | * The following special properties may be passed in via the constructor's vars parameter, like | ||
| 175 | * <code>new TimelineMax({paused:true, onComplete:myFunction, repeat:2, yoyo:true})</code> | ||
| 176 | * | ||
| 177 | * <ul> | ||
| 178 | * <li><b> delay : Number</b> Amount of delay in seconds (or frames for frames-based timelines) before the timeline should begin.</li> | ||
| 179 | * | ||
| 180 | * <li><b> useFrames : Boolean</b> If <code>useFrames</code> is set to true, the timeline's timing mode will be based on frames. | ||
| 181 | * Otherwise, it will be based on seconds/time. NOTE: a TimelineLite's timing mode is | ||
| 182 | * always determined by its parent timeline. </li> | ||
| 183 | * | ||
| 184 | * <li><b> paused : Boolean</b> Sets the initial paused state of the timeline (by default, timelines automatically begin playing immediately)</li> | ||
| 185 | * | ||
| 186 | * <li><b> reversed : Boolean</b> If true, the timeline will be reversed initially. This does NOT force it to the very end and start | ||
| 187 | * playing backwards. It simply affects the orientation of the timeline, so if <code>reversed</code> is set to | ||
| 188 | * true initially, it will appear not to play because it is already at the beginning. To cause it to | ||
| 189 | * play backwards from the end, set reversed to true and then set the <code>currentProgress</code> property to 1 immediately | ||
| 190 | * after creating the timeline.</li> | ||
| 191 | * | ||
| 192 | * <li><b> tweens : Array</b> To immediately insert several tweens into the timeline, use the <code>tweens</code> special property | ||
| 193 | * to pass in an Array of TweenLite/TweenMax/TimelineLite/TimelineMax instances. You can use this in conjunction | ||
| 194 | * with the <code>align</code> and <code>stagger</code> special properties to set up complex sequences with minimal code. | ||
| 195 | * These values simply get passed to the <code>insertMultiple()</code> method.</li> | ||
| 196 | * | ||
| 197 | * <li><b> align : String</b> Only used in conjunction with the <code>tweens</code> special property when multiple tweens are | ||
| 198 | * to be inserted immediately through the constructor. The value simply gets passed to the | ||
| 199 | * <code>insertMultiple()</code> method. The default is <code>TweenAlign.NORMAL</code>. Options are: | ||
| 200 | * <ul> | ||
| 201 | * <li><b> TweenAlign.SEQUENCE:</b> aligns the tweens one-after-the-other in a sequence</li> | ||
| 202 | * <li><b> TweenAlign.START:</b> aligns the start times of all of the tweens (ignores delays)</li> | ||
| 203 | * <li><b> TweenAlign.NORMAL:</b> aligns the start times of all the tweens (honors delays)</li> | ||
| 204 | * </ul>The <code>align</code> special property does <b>not</b> force all child tweens/timelines to maintain | ||
| 205 | * relative positioning, so for example, if you use TweenAlign.SEQUENCE and then later change the duration | ||
| 206 | * of one of the nested tweens, it does <b>not</b> force all subsequent timelines to change their position | ||
| 207 | * on the timeline. The <code>align</code> special property only affects the alignment of the tweens that are | ||
| 208 | * initially placed into the timeline through the <code>tweens</code> special property of the <code>vars</code> object.</li> | ||
| 209 | * | ||
| 210 | * <li><b> stagger : Number</b> Only used in conjunction with the <code>tweens</code> special property when multiple tweens are | ||
| 211 | * to be inserted immediately. It staggers the tweens by a set amount of time (in seconds) (or | ||
| 212 | * in frames if <code>useFrames</code> is true). For example, if the stagger value is 0.5 and the <code>align</code> | ||
| 213 | * property is set to <code>TweenAlign.START</code>, the second tween will start 0.5 seconds after the first one | ||
| 214 | * starts, then 0.5 seconds later the third one will start, etc. If the align property is | ||
| 215 | * <code>TweenAlign.SEQUENCE</code>, there would be 0.5 seconds added between each tween. This value simply gets | ||
| 216 | * passed to the <code>insertMultiple()</code> method. Default is 0.</li> | ||
| 217 | * | ||
| 218 | * <li><b> onStart : Function</b> A function that should be called when the timeline begins (the <code>currentProgress</code> won't necessarily | ||
| 219 | * be zero when onStart is called. For example, if the timeline is created and then its <code>currentProgress</code> | ||
| 220 | * property is immediately set to 0.5 or if its <code>currentTime</code> property is set to something other than zero, | ||
| 221 | * onStart will still get fired because it is the first time the timeline is getting rendered.)</li> | ||
| 222 | * | ||
| 223 | * <li><b> onStartParams : Array</b> An Array of parameters to pass the onStart function.</li> | ||
| 224 | * | ||
| 225 | * <li><b> onUpdate : Function</b> A function that should be called every time the timeline's time/position is updated | ||
| 226 | * (on every frame while the timeline is active)</li> | ||
| 227 | * | ||
| 228 | * <li><b> onUpdateParams : Array</b> An Array of parameters to pass the onUpdate function</li> | ||
| 229 | * | ||
| 230 | * <li><b> onComplete : Function</b> A function that should be called when the timeline has finished </li> | ||
| 231 | * | ||
| 232 | * <li><b> onCompleteParams : Array</b> An Array of parameters to pass the onComplete function</li> | ||
| 233 | * | ||
| 234 | * <li><b> onReverseComplete : Function</b> A function that should be called when the timeline has reached its starting point again after having been reversed </li> | ||
| 235 | * | ||
| 236 | * <li><b> onReverseCompleteParams : Array</b> An Array of parameters to pass the onReverseComplete functions</li> | ||
| 237 | * | ||
| 238 | * <li><b> onRepeat : Function</b> A function that should be called every time the timeline repeats </li> | ||
| 239 | * | ||
| 240 | * <li><b> onRepeatParams : Array</b> An Array of parameters to pass the onRepeat function</li> | ||
| 241 | * | ||
| 242 | * <li><b> autoRemoveChildren : Boolean</b> If autoRemoveChildren is set to true, as soon as child tweens/timelines complete, | ||
| 243 | * they will automatically get killed/removed. This is normally undesireable because | ||
| 244 | * it prevents going backwards in time (like if you want to reverse() or set the | ||
| 245 | * <code>currentProgress</code> value to a lower value, etc.). It can, however, improve speed and memory | ||
| 246 | * management. TweenLite's root timelines use <code>autoRemoveChildren:true</code>.</li> | ||
| 247 | * | ||
| 248 | * <li><b> repeat : int</b> Number of times that the timeline should repeat. To repeat indefinitely, use -1.</li> | ||
| 249 | * | ||
| 250 | * <li><b> repeatDelay : Number</b> Amount of time in seconds (or frames for frames-based timelines) between repeats.</li> | ||
| 251 | * | ||
| 252 | * <li><b> yoyo : Boolean</b> Works in conjunction with the repeat property, determining the behavior of each | ||
| 253 | * cycle. When <code>yoyo</code> is true, the timeline will go back and forth, appearing to reverse | ||
| 254 | * every other cycle (this has no affect on the <code>reversed</code> property though). So if repeat is | ||
| 255 | * 2 and yoyo is false, it will look like: start - 1 - 2 - 3 - 1 - 2 - 3 - 1 - 2 - 3 - end. But | ||
| 256 | * if repeat is 2 and yoyo is true, it will look like: start - 1 - 2 - 3 - 3 - 2 - 1 - 1 - 2 - 3 - end. </li> | ||
| 257 | * | ||
| 258 | * <li><b> onStartListener : Function</b> A function to which the TimelineMax instance should dispatch a TweenEvent when it begins. | ||
| 259 | * This is the same as doing <code>myTimeline.addEventListener(TweenEvent.START, myFunction);</code></li> | ||
| 260 | * | ||
| 261 | * <li><b> onUpdateListener : Function</b> A function to which the TimelineMax instance should dispatch a TweenEvent every time it | ||
| 262 | * updates values. This is the same as doing <code>myTimeline.addEventListener(TweenEvent.UPDATE, myFunction);</code></li> | ||
| 263 | * | ||
| 264 | * <li><b> onCompleteListener : Function</b> A function to which the TimelineMax instance should dispatch a TweenEvent when it completes. | ||
| 265 | * This is the same as doing <code>myTimeline.addEventListener(TweenEvent.COMPLETE, myFunction);</code></li> | ||
| 266 | * </ul> | ||
| 267 | * | ||
| 268 | * @param vars optionally pass in special properties like useFrames, onComplete, onCompleteParams, onUpdate, onUpdateParams, onStart, onStartParams, tweens, align, stagger, delay, autoRemoveChildren, onCompleteListener, onStartListener, onUpdateListener, repeat, repeatDelay, and/or yoyo. | ||
| 269 | */ | ||
| 270 | public function TimelineMax(vars:Object=null) { | ||
| 271 | super(vars); | ||
| 272 | _repeat = (this.vars.repeat) ? Number(this.vars.repeat) : 0; | ||
| 273 | _repeatDelay = (this.vars.repeatDelay) ? Number(this.vars.repeatDelay) : 0; | ||
| 274 | _cyclesComplete = 0; | ||
| 275 | this.yoyo = Boolean(this.vars.yoyo == true); | ||
| 276 | this.cacheIsDirty = true; | ||
| 277 | if (this.vars.onCompleteListener != null || this.vars.onUpdateListener != null || this.vars.onStartListener != null || this.vars.onRepeatListener != null || this.vars.onReverseCompleteListener != null) { | ||
| 278 | initDispatcher(); | ||
| 279 | } | ||
| 280 | } | ||
| 281 | |||
| 282 | /** | ||
| 283 | * If you want a function to be called at a particular time or label, use addCallback. When you add | ||
| 284 | * a callback, it is technically considered a zero-duration tween, so if you getChildren() there will be | ||
| 285 | * a tween returned for each callback. You can discern a callback from other tweens by the fact that | ||
| 286 | * their target is a function and the duration is zero. | ||
| 287 | * | ||
| 288 | * @param function the function to be called | ||
| 289 | * @param timeOrLabel the time in seconds (or frames for frames-based timelines) or label at which the callback should be inserted. For example, myTimeline.addCallback(myFunction, 3) would call myFunction() 3-seconds into the timeline, and myTimeline.addCallback(myFunction, "myLabel") would call it at the "myLabel" label. | ||
| 290 | * @param params an Array of parameters to pass the callback | ||
| 291 | * @return TweenLite instance | ||
| 292 | */ | ||
| 293 | public function addCallback(callback:Function, timeOrLabel:*, params:Array=null):TweenLite { | ||
| 294 | var cb:TweenLite = new TweenLite(callback, 0, {onComplete:callback, onCompleteParams:params, overwrite:0, immediateRender:false}); | ||
| 295 | insert(cb, timeOrLabel); | ||
| 296 | return cb; | ||
| 297 | } | ||
| 298 | |||
| 299 | /** | ||
| 300 | * Removes a callback from a particular time or label. If timeOrLabel is null, all callbacks of that | ||
| 301 | * particular function are removed from the timeline. | ||
| 302 | * | ||
| 303 | * @param function callback function to be removed | ||
| 304 | * @param timeOrLabel the time in seconds (or frames for frames-based timelines) or label from which the callback should be removed. For example, <code>myTimeline.removeCallback(myFunction, 3)</code> would remove the callback from 3-seconds into the timeline, and <code>myTimeline.removeCallback(myFunction, "myLabel")</code> would remove it from the "myLabel" label, and <code>myTimeline.removeCallback(myFunction, null)</code> would remove ALL callbacks of that function regardless of where they are on the timeline. | ||
| 305 | * @return true if any callbacks were successfully found and removed. false otherwise. | ||
| 306 | */ | ||
| 307 | public function removeCallback(callback:Function, timeOrLabel:*=null):Boolean { | ||
| 308 | if (timeOrLabel == null) { | ||
| 309 | return killTweensOf(callback, false); | ||
| 310 | } else { | ||
| 311 | if (typeof(timeOrLabel) == "string") { | ||
| 312 | if (!(timeOrLabel in _labels)) { | ||
| 313 | return false; | ||
| 314 | } | ||
| 315 | timeOrLabel = _labels[timeOrLabel]; | ||
| 316 | } | ||
| 317 | var a:Array = getTweensOf(callback, false), success:Boolean; | ||
| 318 | var i:int = a.length; | ||
| 319 | while (--i > -1) { | ||
| 320 | if (a[i].cachedStartTime == timeOrLabel) { | ||
| 321 | remove(a[i] as TweenCore); | ||
| 322 | success = true; | ||
| 323 | } | ||
| 324 | } | ||
| 325 | return success; | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | /** | ||
| 330 | * Creates a linear tween that essentially scrubs the playhead to a particular time or label and then stops. For | ||
| 331 | * example, to make the TimelineMax play to the "myLabel2" label, simply do: <br /><br /><code> | ||
| 332 | * | ||
| 333 | * myTimeline.tweenTo("myLabel2"); <br /><br /></code> | ||
| 334 | * | ||
| 335 | * If you want advanced control over the tween, like adding an onComplete or changing the ease or adding a delay, | ||
| 336 | * just pass in a vars object with the appropriate properties. For example, to tween to the 5-second point on the | ||
| 337 | * timeline and then call a function named <code>myFunction</code> and pass in a parameter that's references this | ||
| 338 | * TimelineMax and use a Strong.easeOut ease, you'd do: <br /><br /><code> | ||
| 339 | * | ||
| 340 | * myTimeline.tweenTo(5, {onComplete:myFunction, onCompleteParams:[myTimeline], ease:Strong.easeOut});<br /><br /></code> | ||
| 341 | * | ||
| 342 | * Remember, this method simply creates a TweenLite instance that tweens the <code>currentTime</code> property of your timeline. | ||
| 343 | * So you can store a reference to that tween if you want, and you can kill() it anytime. Also note that <code>tweenTo()</code> | ||
| 344 | * does <b>NOT</b> affect the timeline's <code>reversed</code> property. So if your timeline is oriented normally | ||
| 345 | * (not reversed) and you tween to a time/label that precedes the current time, it will appear to go backwards | ||
| 346 | * but the <code>reversed</code> property will <b>not</b> change to <code>true</code>. Also note that <code>tweenTo()</code> | ||
| 347 | * pauses the timeline immediately before tweening its <code>currentTime</code> property, and it stays paused after the tween completes. | ||
| 348 | * If you need to resume playback, you could always use an onComplete to call the <code>resume()</code> method.<br /><br /> | ||
| 349 | * | ||
| 350 | * If you plan to sequence multiple playhead tweens one-after-the-other, it is typically better to use | ||
| 351 | * <code>tweenFromTo()</code> so that you can define the starting point and ending point, allowing the | ||
| 352 | * duration to be accurately determined immediately. | ||
| 353 | * | ||
| 354 | * @see #tweenFromTo() | ||
| 355 | * @param timeOrLabel The destination time in seconds (or frame if the timeline is frames-based) or label to which the timeline should play. For example, myTimeline.tweenTo(5) would play from wherever the timeline is currently to the 5-second point whereas myTimeline.tweenTo("myLabel") would play to wherever "myLabel" is on the timeline. | ||
| 356 | * @param vars An optional vars object that will be passed to the TweenLite instance. This allows you to define an onComplete, ease, delay, or any other TweenLite special property. onInit is the only special property that is not available (tweenTo() sets it internally) | ||
| 357 | * @return TweenLite instance that handles tweening the timeline to the desired time/label. | ||
| 358 | */ | ||
| 359 | public function tweenTo(timeOrLabel:*, vars:Object=null):TweenLite { | ||
| 360 | var varsCopy:Object = {ease:easeNone, overwrite:2, useFrames:this.useFrames, immediateRender:false}; | ||
| 361 | for (var p:String in vars) { | ||
| 362 | varsCopy[p] = vars[p]; | ||
| 363 | } | ||
| 364 | varsCopy.onInit = onInitTweenTo; | ||
| 365 | varsCopy.onInitParams = [null, this, NaN]; | ||
| 366 | varsCopy.currentTime = parseTimeOrLabel(timeOrLabel); | ||
| 367 | var tl:TweenLite = new TweenLite(this, (Math.abs(Number(varsCopy.currentTime) - this.cachedTime) / this.cachedTimeScale) || 0.001, varsCopy); | ||
| 368 | tl.vars.onInitParams[0] = tl; | ||
| 369 | return tl; | ||
| 370 | } | ||
| 371 | |||
| 372 | /** | ||
| 373 | * Creates a linear tween that essentially scrubs the playhead from a particular time or label to another | ||
| 374 | * time or label and then stops. If you plan to sequence multiple playhead tweens one-after-the-other, | ||
| 375 | * <code>tweenFromTo()</code> is better to use than <code>tweenTo()</code> because it allows the duration | ||
| 376 | * to be determined immediately, ensuring that subsequent tweens that are appended to a sequence are | ||
| 377 | * positioned appropriately. For example, to make the TimelineMax play from the label "myLabel1" to the "myLabel2" | ||
| 378 | * label, and then from "myLabel2" back to the beginning (a time of 0), simply do: <br /><br /><code> | ||
| 379 | * | ||
| 380 | * var playheadTweens:TimelineMax = new TimelineMax(); <br /> | ||
| 381 | * playheadTweens.append( myTimeline.tweenFromTo("myLabel1", "myLabel2") );<br /> | ||
| 382 | * playheadTweens.append( myTimeline.tweenFromTo("myLabel2", 0); <br /><br /></code> | ||
| 383 | * | ||
| 384 | * If you want advanced control over the tween, like adding an onComplete or changing the ease or adding a delay, | ||
| 385 | * just pass in a vars object with the appropriate properties. For example, to tween from the start (0) to the | ||
| 386 | * 5-second point on the timeline and then call a function named <code>myFunction</code> and pass in a parameter | ||
| 387 | * that's references this TimelineMax and use a Strong.easeOut ease, you'd do: <br /><br /><code> | ||
| 388 | * | ||
| 389 | * myTimeline.tweenFromTo(0, 5, {onComplete:myFunction, onCompleteParams:[myTimeline], ease:Strong.easeOut});<br /><br /></code> | ||
| 390 | * | ||
| 391 | * Remember, this method simply creates a TweenLite instance that tweens the <code>currentTime</code> property of your timeline. | ||
| 392 | * So you can store a reference to that tween if you want, and you can <code>kill()</code> it anytime. Also note that <code>tweenFromTo()</code> | ||
| 393 | * does <b>NOT</b> affect the timeline's <code>reversed</code> property. So if your timeline is oriented normally | ||
| 394 | * (not reversed) and you tween to a time/label that precedes the current time, it will appear to go backwards | ||
| 395 | * but the <code>reversed</code> property will <b>not</b> change to <code>true</code>. Also note that <code>tweenFromTo()</code> | ||
| 396 | * pauses the timeline immediately before tweening its <code>currentTime</code> property, and it stays paused after the tween completes. | ||
| 397 | * If you need to resume playback, you could always use an onComplete to call the <code>resume()</code> method. | ||
| 398 | * | ||
| 399 | * @see #tweenTo() | ||
| 400 | * @param fromTimeOrLabel The beginning time in seconds (or frame if the timeline is frames-based) or label from which the timeline should play. For example, <code>myTimeline.tweenTo(0, 5)</code> would play from 0 (the beginning) to the 5-second point whereas <code>myTimeline.tweenFromTo("myLabel1", "myLabel2")</code> would play from "myLabel1" to "myLabel2". | ||
| 401 | * @param toTimeOrLabel The destination time in seconds (or frame if the timeline is frames-based) or label to which the timeline should play. For example, <code>myTimeline.tweenTo(0, 5)</code> would play from 0 (the beginning) to the 5-second point whereas <code>myTimeline.tweenFromTo("myLabel1", "myLabel2")</code> would play from "myLabel1" to "myLabel2". | ||
| 402 | * @param vars An optional vars object that will be passed to the TweenLite instance. This allows you to define an onComplete, ease, delay, or any other TweenLite special property. onInit is the only special property that is not available (<code>tweenFromTo()</code> sets it internally) | ||
| 403 | * @return TweenLite instance that handles tweening the timeline between the desired times/labels. | ||
| 404 | */ | ||
| 405 | public function tweenFromTo(fromTimeOrLabel:*, toTimeOrLabel:*, vars:Object=null):TweenLite { | ||
| 406 | var tl:TweenLite = tweenTo(toTimeOrLabel, vars); | ||
| 407 | tl.vars.onInitParams[2] = parseTimeOrLabel(fromTimeOrLabel); | ||
| 408 | tl.duration = Math.abs(Number(tl.vars.currentTime) - tl.vars.onInitParams[2]) / this.cachedTimeScale; | ||
| 409 | return tl; | ||
| 410 | } | ||
| 411 | |||
| 412 | /** @private **/ | ||
| 413 | private static function onInitTweenTo(tween:TweenLite, timeline:TimelineMax, fromTime:Number):void { | ||
| 414 | timeline.paused = true; | ||
| 415 | if (!isNaN(fromTime)) { | ||
| 416 | timeline.currentTime = fromTime; | ||
| 417 | } | ||
| 418 | if (tween.vars.currentTime != timeline.currentTime) { //don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all. | ||
| 419 | tween.duration = Math.abs(Number(tween.vars.currentTime) - timeline.currentTime) / timeline.cachedTimeScale; | ||
| 420 | } | ||
| 421 | } | ||
| 422 | |||
| 423 | /** @private **/ | ||
| 424 | private static function easeNone(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 425 | return t / d; | ||
| 426 | } | ||
| 427 | |||
| 428 | |||
| 429 | /** @private **/ | ||
| 430 | override public function renderTime(time:Number, suppressEvents:Boolean=false, force:Boolean=false):void { | ||
| 431 | if (this.gc) { | ||
| 432 | this.setEnabled(true, false); | ||
| 433 | } else if (!this.active && !this.cachedPaused) { | ||
| 434 | this.active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. | ||
| 435 | } | ||
| 436 | var totalDur:Number = (this.cacheIsDirty) ? this.totalDuration : this.cachedTotalDuration, prevTime:Number = this.cachedTime, prevStart:Number = this.cachedStartTime, prevTimeScale:Number = this.cachedTimeScale, tween:TweenCore, isComplete:Boolean, rendered:Boolean, repeated:Boolean, next:TweenCore, dur:Number, prevPaused:Boolean = this.cachedPaused; | ||
| 437 | if (time >= totalDur) { | ||
| 438 | if (_rawPrevTime <= totalDur && _rawPrevTime != time) { | ||
| 439 | if (!this.cachedReversed && this.yoyo && _repeat % 2 != 0) { | ||
| 440 | forceChildrenToBeginning(0, suppressEvents); | ||
| 441 | this.cachedTime = 0; | ||
| 442 | } else { | ||
| 443 | forceChildrenToEnd(this.cachedDuration, suppressEvents); | ||
| 444 | this.cachedTime = this.cachedDuration; | ||
| 445 | } | ||
| 446 | this.cachedTotalTime = totalDur; | ||
| 447 | isComplete = !this.hasPausedChild(); | ||
| 448 | rendered = true; | ||
| 449 | if (this.cachedDuration == 0 && isComplete && (time == 0 || _rawPrevTime < 0)) { //In order to accommodate zero-duration timelines, we must discern the momentum/direction of time in order to render values properly when the "playhead" goes past 0 in the forward direction or lands directly on it, and also when it moves past it in the backward direction (from a postitive time to a negative time). | ||
| 450 | force = true; | ||
| 451 | } | ||
| 452 | } | ||
| 453 | |||
| 454 | } else if (time <= 0) { | ||
| 455 | if (time < 0) { | ||
| 456 | this.active = false; | ||
| 457 | if (this.cachedDuration == 0 && _rawPrevTime > 0) { //In order to accommodate zero-duration timelines, we must discern the momentum/direction of time in order to render values properly when the "playhead" goes past 0 in the forward direction or lands directly on it, and also when it moves past it in the backward direction (from a postitive time to a negative time). | ||
| 458 | force = true; | ||
| 459 | isComplete = true; | ||
| 460 | } | ||
| 461 | } | ||
| 462 | if (_rawPrevTime >= 0 && _rawPrevTime != time) { | ||
| 463 | this.cachedTotalTime = 0; | ||
| 464 | forceChildrenToBeginning(0, suppressEvents); | ||
| 465 | this.cachedTime = 0; | ||
| 466 | rendered = true; | ||
| 467 | if (this.cachedReversed) { | ||
| 468 | isComplete = true; | ||
| 469 | } | ||
| 470 | } | ||
| 471 | } else { | ||
| 472 | this.cachedTotalTime = this.cachedTime = time; | ||
| 473 | } | ||
| 474 | _rawPrevTime = time; | ||
| 475 | |||
| 476 | if (_repeat != 0) { | ||
| 477 | var cycleDuration:Number = this.cachedDuration + _repeatDelay; | ||
| 478 | if (isComplete) { | ||
| 479 | if (this.yoyo && _repeat % 2) { | ||
| 480 | this.cachedTime = 0; | ||
| 481 | } | ||
| 482 | } else if (time > 0) { | ||
| 483 | var prevCycles:int = _cyclesComplete; | ||
| 484 | _cyclesComplete = int(this.cachedTotalTime / cycleDuration); | ||
| 485 | if (_cyclesComplete == this.cachedTotalTime / cycleDuration) { | ||
| 486 | _cyclesComplete--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning) | ||
| 487 | } | ||
| 488 | if (prevCycles != _cyclesComplete) { | ||
| 489 | repeated = true; | ||
| 490 | } | ||
| 491 | |||
| 492 | this.cachedTime = ((this.cachedTotalTime / cycleDuration) - _cyclesComplete) * cycleDuration; //originally this.cachedTotalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but Flash reports it as 0.79999999!) | ||
| 493 | |||
| 494 | if (this.yoyo && _cyclesComplete % 2) { | ||
| 495 | this.cachedTime = this.cachedDuration - this.cachedTime; | ||
| 496 | } else if (this.cachedTime >= this.cachedDuration) { | ||
| 497 | this.cachedTime = this.cachedDuration; | ||
| 498 | } | ||
| 499 | if (this.cachedTime < 0) { | ||
| 500 | this.cachedTime = 0; | ||
| 501 | } | ||
| 502 | } | ||
| 503 | |||
| 504 | if (repeated && !isComplete && (this.cachedTime != prevTime || force)) { | ||
| 505 | |||
| 506 | /* | ||
| 507 | make sure children at the end/beginning of the timeline are rendered properly. If, for example, | ||
| 508 | a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which | ||
| 509 | would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there | ||
| 510 | could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So | ||
| 511 | we need to push the timeline to the end (and/or beginning depending on its yoyo value). | ||
| 512 | */ | ||
| 513 | |||
| 514 | var forward:Boolean = Boolean(!this.yoyo || (_cyclesComplete % 2 == 0)); | ||
| 515 | var prevForward:Boolean = Boolean(!this.yoyo || (prevCycles % 2 == 0)); | ||
| 516 | var wrap:Boolean = Boolean(forward == prevForward); | ||
| 517 | if (prevCycles > _cyclesComplete) { | ||
| 518 | prevForward = !prevForward; | ||
| 519 | } | ||
| 520 | |||
| 521 | if (prevForward) { | ||
| 522 | prevTime = forceChildrenToEnd(this.cachedDuration, suppressEvents); | ||
| 523 | if (wrap) { | ||
| 524 | prevTime = forceChildrenToBeginning(0, true); | ||
| 525 | } | ||
| 526 | } else { | ||
| 527 | prevTime = forceChildrenToBeginning(0, suppressEvents); | ||
| 528 | if (wrap) { | ||
| 529 | prevTime = forceChildrenToEnd(this.cachedDuration, true); | ||
| 530 | } | ||
| 531 | } | ||
| 532 | rendered = false; | ||
| 533 | } | ||
| 534 | |||
| 535 | } | ||
| 536 | |||
| 537 | if (this.cachedTime == prevTime && !force) { | ||
| 538 | return; | ||
| 539 | } else if (!this.initted) { | ||
| 540 | this.initted = true; | ||
| 541 | } | ||
| 542 | |||
| 543 | if (prevTime == 0 && this.cachedTotalTime != 0 && !suppressEvents) { | ||
| 544 | if (this.vars.onStart) { | ||
| 545 | this.vars.onStart.apply(null, this.vars.onStartParams); | ||
| 546 | } | ||
| 547 | if (_dispatcher) { | ||
| 548 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.START)); | ||
| 549 | } | ||
| 550 | } | ||
| 551 | |||
| 552 | if (rendered) { | ||
| 553 | //already rendered, so ignore | ||
| 554 | } else if (this.cachedTime - prevTime > 0) { | ||
| 555 | tween = _firstChild; | ||
| 556 | while (tween) { | ||
| 557 | next = tween.nextNode; //record it here because the value could change after rendering... | ||
| 558 | if (this.cachedPaused && !prevPaused) { //in case a tween pauses the timeline when rendering | ||
| 559 | break; | ||
| 560 | } else if (tween.active || (!tween.cachedPaused && tween.cachedStartTime <= this.cachedTime && !tween.gc)) { | ||
| 561 | |||
| 562 | if (!tween.cachedReversed) { | ||
| 563 | tween.renderTime((this.cachedTime - tween.cachedStartTime) * tween.cachedTimeScale, suppressEvents, false); | ||
| 564 | } else { | ||
| 565 | dur = (tween.cacheIsDirty) ? tween.totalDuration : tween.cachedTotalDuration; | ||
| 566 | tween.renderTime(dur - ((this.cachedTime - tween.cachedStartTime) * tween.cachedTimeScale), suppressEvents, false); | ||
| 567 | } | ||
| 568 | |||
| 569 | } | ||
| 570 | |||
| 571 | tween = next; | ||
| 572 | } | ||
| 573 | } else { | ||
| 574 | tween = _lastChild; | ||
| 575 | while (tween) { | ||
| 576 | next = tween.prevNode; //record it here because the value could change after rendering... | ||
| 577 | if (this.cachedPaused && !prevPaused) { //in case a tween pauses the timeline when rendering | ||
| 578 | break; | ||
| 579 | } else if (tween.active || (!tween.cachedPaused && tween.cachedStartTime <= prevTime && !tween.gc)) { | ||
| 580 | |||
| 581 | if (!tween.cachedReversed) { | ||
| 582 | tween.renderTime((this.cachedTime - tween.cachedStartTime) * tween.cachedTimeScale, suppressEvents, false); | ||
| 583 | } else { | ||
| 584 | dur = (tween.cacheIsDirty) ? tween.totalDuration : tween.cachedTotalDuration; | ||
| 585 | tween.renderTime(dur - ((this.cachedTime - tween.cachedStartTime) * tween.cachedTimeScale), suppressEvents, false); | ||
| 586 | } | ||
| 587 | |||
| 588 | } | ||
| 589 | |||
| 590 | tween = next; | ||
| 591 | } | ||
| 592 | } | ||
| 593 | if (_hasUpdate && !suppressEvents) { | ||
| 594 | this.vars.onUpdate.apply(null, this.vars.onUpdateParams); | ||
| 595 | } | ||
| 596 | if (_hasUpdateListener && !suppressEvents) { | ||
| 597 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.UPDATE)); | ||
| 598 | } | ||
| 599 | if (isComplete && (prevStart == this.cachedStartTime || prevTimeScale != this.cachedTimeScale) && (totalDur >= this.totalDuration || this.cachedTime == 0)) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline) or if it added more tweens to the timeline, we shouldn't run complete() because it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would have called complete() if it was necessary at the new time. The only exception is the timeScale property. | ||
| 600 | complete(true, suppressEvents); | ||
| 601 | } else if (repeated && !suppressEvents) { | ||
| 602 | if (this.vars.onRepeat) { | ||
| 603 | this.vars.onRepeat.apply(null, this.vars.onRepeatParams); | ||
| 604 | } | ||
| 605 | if (_dispatcher) { | ||
| 606 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.REPEAT)); | ||
| 607 | } | ||
| 608 | } | ||
| 609 | } | ||
| 610 | |||
| 611 | /** | ||
| 612 | * Forces the timeline to completion. | ||
| 613 | * | ||
| 614 | * @param skipRender to skip rendering the final state of the timeline, set skipRender to true. | ||
| 615 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 616 | */ | ||
| 617 | override public function complete(skipRender:Boolean=false, suppressEvents:Boolean=false):void { | ||
| 618 | super.complete(skipRender, suppressEvents); | ||
| 619 | if (_dispatcher && !suppressEvents) { | ||
| 620 | if (this.cachedReversed && this.cachedTotalTime == 0 && this.cachedDuration != 0) { | ||
| 621 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.REVERSE_COMPLETE)); | ||
| 622 | } else { | ||
| 623 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.COMPLETE)); | ||
| 624 | } | ||
| 625 | } | ||
| 626 | } | ||
| 627 | |||
| 628 | /** | ||
| 629 | * Returns the tweens/timelines that are currently active in the timeline. | ||
| 630 | * | ||
| 631 | * @param nested determines whether or not tweens and/or timelines that are inside nested timelines should be returned. If you only want the "top level" tweens/timelines, set this to false. | ||
| 632 | * @param tweens determines whether or not tweens (TweenLite and TweenMax instances) should be included in the results | ||
| 633 | * @param timelines determines whether or not timelines (TimelineLite and TimelineMax instances) should be included in the results | ||
| 634 | * @return an Array of active tweens/timelines | ||
| 635 | */ | ||
| 636 | public function getActive(nested:Boolean=true, tweens:Boolean=true, timelines:Boolean=false):Array { | ||
| 637 | var a:Array = [], all:Array = getChildren(nested, tweens, timelines), i:int; | ||
| 638 | var l:uint = all.length; | ||
| 639 | var cnt:uint = 0; | ||
| 640 | for (i = 0; i < l; i++) { | ||
| 641 | if (TweenCore(all[i]).active) { | ||
| 642 | a[cnt++] = all[i]; | ||
| 643 | } | ||
| 644 | } | ||
| 645 | return a; | ||
| 646 | } | ||
| 647 | |||
| 648 | /** @inheritDoc **/ | ||
| 649 | override public function invalidate():void { | ||
| 650 | _repeat = (this.vars.repeat) ? Number(this.vars.repeat) : 0; | ||
| 651 | _repeatDelay = (this.vars.repeatDelay) ? Number(this.vars.repeatDelay) : 0; | ||
| 652 | this.yoyo = Boolean(this.vars.yoyo == true); | ||
| 653 | if (this.vars.onCompleteListener != null || this.vars.onUpdateListener != null || this.vars.onStartListener != null || this.vars.onRepeatListener != null || this.vars.onReverseCompleteListener != null) { | ||
| 654 | initDispatcher(); | ||
| 655 | } | ||
| 656 | setDirtyCache(true); | ||
| 657 | super.invalidate(); | ||
| 658 | } | ||
| 659 | |||
| 660 | /** | ||
| 661 | * Returns the next label (if any) that occurs AFTER the time parameter. It makes no difference | ||
| 662 | * if the timeline is reversed. A label that is positioned exactly at the same time as the <code>time</code> | ||
| 663 | * parameter will be ignored. | ||
| 664 | * | ||
| 665 | * @param time Time after which the label is searched for. If you do not pass a time in, the currentTime will be used. | ||
| 666 | * @return Name of the label that is after the time passed to getLabelAfter() | ||
| 667 | */ | ||
| 668 | public function getLabelAfter(time:Number=NaN):String { | ||
| 669 | if (!time && time != 0) { //faster than isNan() | ||
| 670 | time = this.cachedTime; | ||
| 671 | } | ||
| 672 | var labels:Array = getLabelsArray(); | ||
| 673 | var l:uint = labels.length; | ||
| 674 | for (var i:int = 0; i < l; i++) { | ||
| 675 | if (labels[i].time > time) { | ||
| 676 | return labels[i].name; | ||
| 677 | } | ||
| 678 | } | ||
| 679 | return null; | ||
| 680 | } | ||
| 681 | |||
| 682 | /** | ||
| 683 | * Returns the previous label (if any) that occurs BEFORE the time parameter. It makes no difference | ||
| 684 | * if the timeline is reversed. A label that is positioned exactly at the same time as the <code>time</code> | ||
| 685 | * parameter will be ignored. | ||
| 686 | * | ||
| 687 | * @param time Time before which the label is searched for. If you do not pass a time in, the currentTime will be used. | ||
| 688 | * @return Name of the label that is before the time passed to getLabelBefore() | ||
| 689 | */ | ||
| 690 | public function getLabelBefore(time:Number=NaN):String { | ||
| 691 | if (!time && time != 0) { //faster than isNan() | ||
| 692 | time = this.cachedTime; | ||
| 693 | } | ||
| 694 | var labels:Array = getLabelsArray(); | ||
| 695 | var i:int = labels.length; | ||
| 696 | while (--i > -1) { | ||
| 697 | if (labels[i].time < time) { | ||
| 698 | return labels[i].name; | ||
| 699 | } | ||
| 700 | } | ||
| 701 | return null; | ||
| 702 | } | ||
| 703 | |||
| 704 | /** @private Returns an Array of label objects, each with a "time" and "name" property, in the order that they occur in the timeline. **/ | ||
| 705 | protected function getLabelsArray():Array { | ||
| 706 | var a:Array = []; | ||
| 707 | for (var p:String in _labels) { | ||
| 708 | a[a.length] = {time:_labels[p], name:p}; | ||
| 709 | } | ||
| 710 | a.sortOn("time", Array.NUMERIC); | ||
| 711 | return a; | ||
| 712 | } | ||
| 713 | |||
| 714 | |||
| 715 | //---- EVENT DISPATCHING ---------------------------------------------------------------------------------------------------------- | ||
| 716 | |||
| 717 | /** @private **/ | ||
| 718 | protected function initDispatcher():void { | ||
| 719 | if (_dispatcher == null) { | ||
| 720 | _dispatcher = new EventDispatcher(this); | ||
| 721 | } | ||
| 722 | if (this.vars.onStartListener is Function) { | ||
| 723 | _dispatcher.addEventListener(TweenEvent.START, this.vars.onStartListener, false, 0, true); | ||
| 724 | } | ||
| 725 | if (this.vars.onUpdateListener is Function) { | ||
| 726 | _dispatcher.addEventListener(TweenEvent.UPDATE, this.vars.onUpdateListener, false, 0, true); | ||
| 727 | _hasUpdateListener = true; | ||
| 728 | } | ||
| 729 | if (this.vars.onCompleteListener is Function) { | ||
| 730 | _dispatcher.addEventListener(TweenEvent.COMPLETE, this.vars.onCompleteListener, false, 0, true); | ||
| 731 | } | ||
| 732 | if (this.vars.onRepeatListener is Function) { | ||
| 733 | _dispatcher.addEventListener(TweenEvent.REPEAT, this.vars.onRepeatListener, false, 0, true); | ||
| 734 | } | ||
| 735 | if (this.vars.onReverseCompleteListener is Function) { | ||
| 736 | _dispatcher.addEventListener(TweenEvent.REVERSE_COMPLETE, this.vars.onReverseCompleteListener, false, 0, true); | ||
| 737 | } | ||
| 738 | } | ||
| 739 | /** @private **/ | ||
| 740 | public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void { | ||
| 741 | if (_dispatcher == null) { | ||
| 742 | initDispatcher(); | ||
| 743 | } | ||
| 744 | if (type == TweenEvent.UPDATE) { | ||
| 745 | _hasUpdateListener = true; | ||
| 746 | } | ||
| 747 | _dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference); | ||
| 748 | } | ||
| 749 | /** @private **/ | ||
| 750 | public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void { | ||
| 751 | if (_dispatcher != null) { | ||
| 752 | _dispatcher.removeEventListener(type, listener, useCapture); | ||
| 753 | } | ||
| 754 | } | ||
| 755 | /** @private **/ | ||
| 756 | public function hasEventListener(type:String):Boolean { | ||
| 757 | return (_dispatcher == null) ? false : _dispatcher.hasEventListener(type); | ||
| 758 | } | ||
| 759 | /** @private **/ | ||
| 760 | public function willTrigger(type:String):Boolean { | ||
| 761 | return (_dispatcher == null) ? false : _dispatcher.willTrigger(type); | ||
| 762 | } | ||
| 763 | /** @private **/ | ||
| 764 | public function dispatchEvent(e:Event):Boolean { | ||
| 765 | return (_dispatcher == null) ? false : _dispatcher.dispatchEvent(e); | ||
| 766 | } | ||
| 767 | |||
| 768 | |||
| 769 | //---- GETTERS / SETTERS ------------------------------------------------------------------------------------------------------- | ||
| 770 | |||
| 771 | |||
| 772 | |||
| 773 | /** | ||
| 774 | * Value between 0 and 1 indicating the overall progress of the timeline according to its <code>totalDuration</code> | ||
| 775 | * where 0 is at the beginning, 0.5 is halfway finished, and 1 is finished. <code>currentProgress</code>, | ||
| 776 | * by contrast, describes the progress according to the timeline's duration which does not | ||
| 777 | * include repeats and repeatDelays. For example, if a TimelineMax instance is set | ||
| 778 | * to repeat once, at the end of the first cycle <code>totalProgress</code> would only be 0.5 | ||
| 779 | * whereas <code>currentProgress</code> would be 1. If you tracked both properties over the course of the | ||
| 780 | * tween, you'd see <code>currentProgress</code> go from 0 to 1 twice (once for each cycle) in the same | ||
| 781 | * time it takes the <code>totalProgress</code> property to go from 0 to 1 once. | ||
| 782 | **/ | ||
| 783 | public function get totalProgress():Number { | ||
| 784 | return this.cachedTotalTime / this.totalDuration; | ||
| 785 | } | ||
| 786 | |||
| 787 | public function set totalProgress(n:Number):void { | ||
| 788 | setTotalTime(this.totalDuration * n, false); | ||
| 789 | } | ||
| 790 | |||
| 791 | /** | ||
| 792 | * Duration of the timeline in seconds (or frames for frames-based timelines) including any repeats | ||
| 793 | * or repeatDelays. "duration", by contrast, does NOT include repeats and repeatDelays. | ||
| 794 | **/ | ||
| 795 | override public function get totalDuration():Number { | ||
| 796 | if (this.cacheIsDirty) { | ||
| 797 | var temp:Number = super.totalDuration; //just forces refresh | ||
| 798 | //Instead of Infinity, we use 999999999999 so that we can accommodate reverses. | ||
| 799 | this.cachedTotalDuration = (_repeat == -1) ? 999999999999 : this.cachedDuration * (_repeat + 1) + (_repeatDelay * _repeat); | ||
| 800 | } | ||
| 801 | return this.cachedTotalDuration; | ||
| 802 | } | ||
| 803 | |||
| 804 | /** @inheritDoc **/ | ||
| 805 | override public function set currentTime(n:Number):void { | ||
| 806 | if (_cyclesComplete == 0) { | ||
| 807 | setTotalTime(n, false); | ||
| 808 | } else if (this.yoyo && (_cyclesComplete % 2 == 1)) { | ||
| 809 | setTotalTime((this.duration - n) + (_cyclesComplete * (this.cachedDuration + _repeatDelay)), false); | ||
| 810 | } else { | ||
| 811 | setTotalTime(n + (_cyclesComplete * (this.duration + _repeatDelay)), false); | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | /** Number of times that the timeline should repeat; -1 repeats indefinitely. **/ | ||
| 816 | public function get repeat():int { | ||
| 817 | return _repeat; | ||
| 818 | } | ||
| 819 | |||
| 820 | public function set repeat(n:int):void { | ||
| 821 | _repeat = n; | ||
| 822 | setDirtyCache(true); | ||
| 823 | } | ||
| 824 | |||
| 825 | /** Amount of time in seconds (or frames for frames-based timelines) between repeats **/ | ||
| 826 | public function get repeatDelay():Number { | ||
| 827 | return _repeatDelay; | ||
| 828 | } | ||
| 829 | |||
| 830 | public function set repeatDelay(n:Number):void { | ||
| 831 | _repeatDelay = n; | ||
| 832 | setDirtyCache(true); | ||
| 833 | } | ||
| 834 | |||
| 835 | /** The closest label that is at or before the current time. **/ | ||
| 836 | public function get currentLabel():String { | ||
| 837 | return getLabelBefore(this.cachedTime + 0.00000001); | ||
| 838 | } | ||
| 839 | |||
| 840 | } | ||
| 841 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.86 | ||
| 3 | * DATE: 6/15/2009 | ||
| 4 | * AS2 (AS3 version is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | package com.greensock { | ||
| 8 | /** | ||
| 9 | * Static constants for defining tween alignment. | ||
| 10 | * | ||
| 11 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 12 | * | ||
| 13 | * @author Jack Doyle, jack@greensock.com | ||
| 14 | **/ | ||
| 15 | public class TweenAlign { | ||
| 16 | public static const NORMAL:String = "normal"; | ||
| 17 | public static const SEQUENCE:String = "sequence"; | ||
| 18 | public static const START:String = "start"; | ||
| 19 | } | ||
| 20 | |||
| 21 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 11.36 | ||
| 3 | * DATE: 2010-04-27 | ||
| 4 | * AS3 (AS2 version is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | package com.greensock { | ||
| 8 | import com.greensock.core.*; | ||
| 9 | import com.greensock.plugins.*; | ||
| 10 | |||
| 11 | import flash.display.*; | ||
| 12 | import flash.events.*; | ||
| 13 | import flash.utils.*; | ||
| 14 | /** | ||
| 15 | * TweenLite is an extremely fast, lightweight, and flexible tweening engine that serves as the foundation of | ||
| 16 | * the GreenSock Tweening Platform. A TweenLite instance handles tweening one or more numeric properties of any | ||
| 17 | * object over time, updating them on every frame. Sounds simple, but there's a wealth of capabilities and conveniences | ||
| 18 | * at your fingertips with TweenLite. With plenty of other tweening engines to choose from, here's why you might | ||
| 19 | * want to consider TweenLite: | ||
| 20 | * <ul> | ||
| 21 | * <li><b> SPEED </b>- TweenLite has been highly optimized for maximum performance. See some speed comparisons yourself at | ||
| 22 | * <a href="http://www.greensock.com/tweening-speed-test/">http://www.greensock.com/tweening-speed-test/</a></li> | ||
| 23 | * | ||
| 24 | * <li><b> Feature set </b>- In addition to tweening ANY numeric property of ANY object, TweenLite can tween filters, | ||
| 25 | * hex colors, volume, tint, frames, and even do bezier tweening, plus LOTS more. TweenMax extends | ||
| 26 | * TweenLite and adds even more capabilities like repeat, yoyo, repeatDelay, timeScale, event dispatching, on-the-fly | ||
| 27 | * destination value updates, rounding and more. Overwrite management is an important consideration in | ||
| 28 | * a tweening engine as well which is another area where the GreenSock Tweening Platform shines. | ||
| 29 | * You have options for AUTO overwriting or you can manually define how each tween will handle overlapping | ||
| 30 | * tweens of the same object.</li> | ||
| 31 | * | ||
| 32 | * <li><b> Expandability </b>- With its plugin architecture, you can activate as many (or as few) features as your | ||
| 33 | * project requires. Write your own plugin to handle particular special properties in custom ways. Minimize bloat, and | ||
| 34 | * maximize performance.</li> | ||
| 35 | * | ||
| 36 | * <li><b> Sequencing, grouping, and management features </b>- TimelineLite and TimelineMax make it surprisingly | ||
| 37 | * simple to create complex sequences or groups of tweens that you can control as a whole. play(), pause(), restart(), | ||
| 38 | * or reverse(). You can even tween a timeline's <code>currentTime</code> or <code>currentProgress</code> property | ||
| 39 | * to fastforward or rewind the entire timeline. Add labels, gotoAndPlay(), change the timeline's timeScale, nest | ||
| 40 | * timelines within timelines, and lots more.</li> | ||
| 41 | * | ||
| 42 | * <li><b> Ease of use </b>- Designers and Developers alike rave about how intuitive the platform is.</li> | ||
| 43 | * | ||
| 44 | * <li><b> Updates </b>- Frequent updates and feature additions make the GreenSock Tweening Platform reliable and robust.</li> | ||
| 45 | * | ||
| 46 | * <li><b> AS2 and AS3 </b>- Most other engines are only developed for AS2 or AS3 but not both.</li> | ||
| 47 | * </ul> | ||
| 48 | * | ||
| 49 | * <hr /> | ||
| 50 | * <b>SPECIAL PROPERTIES (no plugins required):</b> | ||
| 51 | * <br /><br /> | ||
| 52 | * | ||
| 53 | * Any of the following special properties can optionally be passed in through the vars object (the third parameter): | ||
| 54 | * | ||
| 55 | * <ul> | ||
| 56 | * <li><b> delay : Number</b> Amount of delay in seconds (or frames for frames-based tweens) before the tween should begin.</li> | ||
| 57 | * | ||
| 58 | * <li><b> useFrames : Boolean</b> If useFrames is set to true, the tweens's timing mode will be based on frames. | ||
| 59 | * Otherwise, it will be based on seconds/time. NOTE: a tween's timing mode is | ||
| 60 | * always determined by its parent timeline. </li> | ||
| 61 | * | ||
| 62 | * <li><b> ease : Function</b> Use any standard easing equation to control the rate of change. For example, | ||
| 63 | * <code>Elastic.easeOut</code>. The Default is Quad.easeOut.</li> | ||
| 64 | * | ||
| 65 | * <li><b> easeParams : Array</b> An Array of extra parameters to feed the easing equation. This can be useful when | ||
| 66 | * using an ease like <code>Elastic</code> and want to control extra parameters like the amplitude | ||
| 67 | * and period. Most easing equations, however, don't require extra parameters so you | ||
| 68 | * won't need to pass in any easeParams.</li> | ||
| 69 | * | ||
| 70 | * <li><b> immediateRender : Boolean</b> Normally when you create a tween, it begins rendering on the very next frame (when | ||
| 71 | * the Flash Player dispatches an ENTER_FRAME event) unless you specify a <code>delay</code>. This | ||
| 72 | * allows you to insert tweens into timelines and perform other actions that may affect | ||
| 73 | * its timing. However, if you prefer to force the tween to render immediately when it is | ||
| 74 | * created, set <code>immediateRender</code> to true. Or to prevent a tween with a duration of zero from | ||
| 75 | * rendering immediately, set <code>immediateRender</code> to false.</li> | ||
| 76 | * | ||
| 77 | * <li><b> onInit : Function</b> A function that should be called just before the tween inits (renders for the first time). | ||
| 78 | * Since onInit runs before the start/end values are recorded internally, it is a good place to run | ||
| 79 | * code that affects the target's initial position or other tween-related properties. onStart, by | ||
| 80 | * contrast, runs AFTER the tween inits and the start/end values are recorded internally. onStart | ||
| 81 | * is called every time the tween begins which can happen more than once if the tween is restarted | ||
| 82 | * multiple times.</li> | ||
| 83 | * | ||
| 84 | * <li><b> onInitParams : Array</b> An Array of parameters to pass the onInit function.</li> | ||
| 85 | * | ||
| 86 | * <li><b> onStart : Function</b> A function that should be called when the tween begins (when its currentTime is at 0 and | ||
| 87 | * changes to some other value which can happen more than once if the tween is restarted multiple times).</li> | ||
| 88 | * | ||
| 89 | * <li><b> onStartParams : Array</b> An Array of parameters to pass the onStart function.</li> | ||
| 90 | * | ||
| 91 | * <li><b> onUpdate : Function</b> A function that should be called every time the tween's time/position is updated | ||
| 92 | * (on every frame while the tween is active)</li> | ||
| 93 | * | ||
| 94 | * <li><b> onUpdateParams : Array</b> An Array of parameters to pass the onUpdate function</li> | ||
| 95 | * | ||
| 96 | * <li><b> onComplete : Function</b> A function that should be called when the tween has finished </li> | ||
| 97 | * | ||
| 98 | * <li><b> onCompleteParams : Array</b> An Array of parameters to pass the onComplete function</li> | ||
| 99 | * | ||
| 100 | * <li><b> onReverseComplete : Function</b> A function that should be called when the tween has reached its starting point again after having been reversed. </li> | ||
| 101 | * | ||
| 102 | * <li><b> onReverseCompleteParams : Array</b> An Array of parameters to pass the onReverseComplete function</li> | ||
| 103 | * | ||
| 104 | * <li><b> paused : Boolean</b> If true, the tween will be paused initially.</li> | ||
| 105 | * | ||
| 106 | * <li><b> overwrite : int</b> Controls how (and if) other tweens of the same target are overwritten by this tween. There are | ||
| 107 | * several modes to choose from, but only the first two are available in TweenLite unless | ||
| 108 | * <code>OverwriteManager.init()</code> has been called (please see | ||
| 109 | * <a href="http://www.greensock.com/overwritemanager/">http://www.greensock.com/overwritemanager/</a> | ||
| 110 | * for details and a full explanation of the various modes): | ||
| 111 | * <ul> | ||
| 112 | * <li>NONE (0) (or false) </li> | ||
| 113 | * | ||
| 114 | * <li>ALL_IMMEDIATE (1) (or true) - this is the default mode in TweenLite</li> | ||
| 115 | * | ||
| 116 | * <li>AUTO (2) - this is the default mode if TweenMax, TimelineLite, or TimelineMax is used in the swf. (these classes automatically init() OverwriteManager if you haven't done so already)</li> | ||
| 117 | * | ||
| 118 | * <li>CONCURRENT (3) (requires OverwriteManager)</li> | ||
| 119 | * | ||
| 120 | * <li>ALL_ONSTART (4) (requires OverwriteManager)</li> | ||
| 121 | * | ||
| 122 | * <li>PREEXISTING (5) (requires OverwriteManager)</li> | ||
| 123 | * | ||
| 124 | * </ul></li> | ||
| 125 | * </ul> | ||
| 126 | * | ||
| 127 | * <b>PLUGINS:</b><br /><br /> | ||
| 128 | * | ||
| 129 | * There are many plugins that add capabilities through other special properties. Some examples are "tint", | ||
| 130 | * "volume", "frame", "frameLabel", "bezier", "blurFilter", "colorMatrixFilter", "hexColors", and many more. | ||
| 131 | * Adding the capabilities is as simple as activating the plugin with a single line of code, like | ||
| 132 | * TweenPlugin.activate([TintPlugin]); Get information about all the plugins at | ||
| 133 | * <a href="http://www.TweenLite.com">http://www.TweenLite.com</a><br /><br /> | ||
| 134 | * | ||
| 135 | * <b>EXAMPLES:</b> <br /><br /> | ||
| 136 | * | ||
| 137 | * Please see <a href="http://www.tweenlite.com">http://www.tweenlite.com</a> for examples, tutorials, and interactive demos. <br /><br /> | ||
| 138 | * | ||
| 139 | * <b>NOTES / TIPS:</b><br /><br /> | ||
| 140 | * <ul> | ||
| 141 | * <li> The base TweenLite class adds about 4.7kb to your compressed swf (if no plugins are activated)</li> | ||
| 142 | * | ||
| 143 | * <li> Passing values as Strings will make the tween relative to the current value. For example, if you do | ||
| 144 | * <code>TweenLite.to(mc, 2, {x:"-20"});</code> it'll move the mc.x to the left 20 pixels which is the same as doing | ||
| 145 | * <code>TweenLite.to(mc, 2, {x:mc.x - 20});</code> You could also cast it like: <code>TweenLite.to(mc, 2, {x:String(myVariable)});</code></li> | ||
| 146 | * | ||
| 147 | * <li> You can change the <code>TweenLite.defaultEase</code> function if you prefer something other than <code>Regular.easeOut</code>.</li> | ||
| 148 | * | ||
| 149 | * <li> Kill all tweens for a particular object anytime with the <code>TweenLite.killTweensOf(mc); </code></li> | ||
| 150 | * | ||
| 151 | * <li> You can kill all delayedCalls to a particular function using <code>TweenLite.killDelayedCallsTo(myFunction);</code> | ||
| 152 | * This can be helpful if you want to preempt a call.</li> | ||
| 153 | * | ||
| 154 | * <li> Use the <code>TweenLite.from()</code> method to animate things into place. For example, if you have things set up on | ||
| 155 | * the stage in the spot where they should end up, and you just want to animate them into place, you can | ||
| 156 | * pass in the beginning x and/or y and/or alpha (or whatever properties you want).</li> | ||
| 157 | * | ||
| 158 | * <li> If you find this class useful, please consider joining Club GreenSock which not only helps to sustain | ||
| 159 | * ongoing development, but also gets you bonus plugins, classes and other benefits that are ONLY available | ||
| 160 | * to members. Learn more at <a href="http://www.greensock.com/club/">http://www.greensock.com/club/</a></li> | ||
| 161 | * </ul> | ||
| 162 | * | ||
| 163 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 164 | * | ||
| 165 | * @author Jack Doyle, jack@greensock.com | ||
| 166 | */ | ||
| 167 | public class TweenLite extends TweenCore { | ||
| 168 | |||
| 169 | /** | ||
| 170 | * @private | ||
| 171 | * Initializes the class, activates default plugins, and starts the root timelines. This should only | ||
| 172 | * be called internally. It is technically public only so that other classes in the GreenSock Tweening | ||
| 173 | * Platform can access it, but again, please avoid calling this method directly. | ||
| 174 | */ | ||
| 175 | public static function initClass():void { | ||
| 176 | |||
| 177 | |||
| 178 | //ACTIVATE PLUGINS HERE... | ||
| 179 | /* | ||
| 180 | TweenPlugin.activate([ | ||
| 181 | |||
| 182 | AutoAlphaPlugin, //tweens alpha and then toggles "visible" to false if/when alpha is zero | ||
| 183 | EndArrayPlugin, //tweens numbers in an Array | ||
| 184 | FramePlugin, //tweens MovieClip frames | ||
| 185 | RemoveTintPlugin, //allows you to remove a tint | ||
| 186 | TintPlugin, //tweens tints | ||
| 187 | VisiblePlugin, //tweens a target's "visible" property | ||
| 188 | VolumePlugin, //tweens the volume of a MovieClip or SoundChannel or anything with a "soundTransform" property | ||
| 189 | |||
| 190 | BevelFilterPlugin, //tweens BevelFilters | ||
| 191 | BezierPlugin, //enables bezier tweening | ||
| 192 | BezierThroughPlugin, //enables bezierThrough tweening | ||
| 193 | BlurFilterPlugin, //tweens BlurFilters | ||
| 194 | ColorMatrixFilterPlugin, //tweens ColorMatrixFilters (including hue, saturation, colorize, contrast, brightness, and threshold) | ||
| 195 | DropShadowFilterPlugin, //tweens DropShadowFilters | ||
| 196 | GlowFilterPlugin, //tweens GlowFilters | ||
| 197 | HexColorsPlugin, //tweens hex colors | ||
| 198 | ShortRotationPlugin, //tweens rotation values in the shortest direction | ||
| 199 | |||
| 200 | ColorTransformPlugin, //tweens advanced color properties like exposure, brightness, tintAmount, redOffset, redMultiplier, etc. | ||
| 201 | FrameLabelPlugin, //tweens a MovieClip to particular label | ||
| 202 | QuaternionsPlugin, //tweens 3D Quaternions | ||
| 203 | ScalePlugin, //Tweens both the _xscale and _yscale properties | ||
| 204 | ScrollRectPlugin, //tweens the scrollRect property of a DisplayObject | ||
| 205 | SetSizePlugin, //tweens the width/height of components via setSize() | ||
| 206 | SetActualSizePlugin //tweens the width/height of components via setActualSize() | ||
| 207 | TransformMatrixPlugin, //Tweens the transform.matrix property of any DisplayObject | ||
| 208 | |||
| 209 | //DynamicPropsPlugin, //tweens to dynamic end values. You associate the property with a particular function that returns the target end value **Club GreenSock membership benefit** | ||
| 210 | //MotionBlurPlugin, //applies a directional blur to a DisplayObject based on the velocity and angle of movement. **Club GreenSock membership benefit** | ||
| 211 | //Physics2DPlugin, //allows you to apply basic physics in 2D space, like velocity, angle, gravity, friction, acceleration, and accelerationAngle. **Club GreenSock membership benefit** | ||
| 212 | //PhysicsPropsPlugin, //allows you to apply basic physics to any property using forces like velocity, acceleration, and/or friction. **Club GreenSock membership benefit** | ||
| 213 | //TransformAroundCenterPlugin,//tweens the scale and/or rotation of DisplayObjects using the DisplayObject's center as the registration point **Club GreenSock membership benefit** | ||
| 214 | //TransformAroundPointPlugin, //tweens the scale and/or rotation of DisplayObjects around a particular point (like a custom registration point) **Club GreenSock membership benefit** | ||
| 215 | |||
| 216 | |||
| 217 | {}]); | ||
| 218 | */ | ||
| 219 | |||
| 220 | rootFrame = 0; | ||
| 221 | rootTimeline = new SimpleTimeline(null); | ||
| 222 | rootFramesTimeline = new SimpleTimeline(null); | ||
| 223 | rootTimeline.cachedStartTime = getTimer() * 0.001; | ||
| 224 | rootFramesTimeline.cachedStartTime = rootFrame; | ||
| 225 | rootTimeline.autoRemoveChildren = true; | ||
| 226 | rootFramesTimeline.autoRemoveChildren = true; | ||
| 227 | _shape.addEventListener(Event.ENTER_FRAME, updateAll, false, 0, true); | ||
| 228 | if (overwriteManager == null) { | ||
| 229 | overwriteManager = {mode:1, enabled:false}; | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | /** @private **/ | ||
| 234 | public static const version:Number = 11.36; | ||
| 235 | /** @private When plugins are activated, the class is added (named based on the special property) to this object so that we can quickly look it up in the initTweenVals() method.**/ | ||
| 236 | public static var plugins:Object = {}; | ||
| 237 | /** @private **/ | ||
| 238 | public static var fastEaseLookup:Dictionary = new Dictionary(false); | ||
| 239 | /** @private For notifying plugins of significant events like when the tween finishes initializing, when it is disabled/enabled, and when it completes (some plugins need to take actions when those events occur) **/ | ||
| 240 | public static var onPluginEvent:Function; | ||
| 241 | /** @private **/ | ||
| 242 | public static var killDelayedCallsTo:Function = TweenLite.killTweensOf; | ||
| 243 | /** Provides an easy way to change the default easing equation.**/ | ||
| 244 | public static var defaultEase:Function = TweenLite.easeOut; | ||
| 245 | /** @private Makes it possible to integrate OverwriteManager for adding various overwriting capabilities. **/ | ||
| 246 | public static var overwriteManager:Object; | ||
| 247 | /** @private Gets updated on every frame. This syncs all the tweens and prevents drifting of the startTime that happens under heavy loads with most other engines.**/ | ||
| 248 | public static var rootFrame:Number; | ||
| 249 | /** @private All tweens get associated with a timeline. The rootTimeline is the default for all time-based tweens.**/ | ||
| 250 | public static var rootTimeline:SimpleTimeline; | ||
| 251 | /** @private All tweens get associated with a timeline. The rootFramesTimeline is the default for all frames-based tweens.**/ | ||
| 252 | public static var rootFramesTimeline:SimpleTimeline; | ||
| 253 | /** @private Holds references to all our tween instances organized by target for quick lookups (for overwriting).**/ | ||
| 254 | public static var masterList:Dictionary = new Dictionary(false); | ||
| 255 | /** @private Drives all our ENTER_FRAME events.**/ | ||
| 256 | private static var _shape:Shape = new Shape(); | ||
| 257 | /** @private Lookup for all of the reserved "special property" keywords.**/ | ||
| 258 | protected static var _reservedProps:Object = {ease:1, delay:1, overwrite:1, onComplete:1, onCompleteParams:1, useFrames:1, runBackwards:1, startAt:1, onUpdate:1, onUpdateParams:1, roundProps:1, onStart:1, onStartParams:1, onInit:1, onInitParams:1, onReverseComplete:1, onReverseCompleteParams:1, onRepeat:1, onRepeatParams:1, proxiedEase:1, easeParams:1, yoyo:1, onCompleteListener:1, onUpdateListener:1, onStartListener:1, onReverseCompleteListener:1, onRepeatListener:1, orientToBezier:1, timeScale:1, immediateRender:1, repeat:1, repeatDelay:1, timeline:1, data:1, paused:1}; | ||
| 259 | |||
| 260 | |||
| 261 | /** Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. **/ | ||
| 262 | public var target:Object; | ||
| 263 | /** @private Lookup object for PropTween objects. For example, if this tween is handling the "x" and "y" properties of the target, the propTweenLookup object will have an "x" and "y" property, each pointing to the associated PropTween object. This can be very helpful for speeding up overwriting. This is a public variable, but should almost never be used directly. **/ | ||
| 264 | public var propTweenLookup:Object; | ||
| 265 | /** @private result of _ease(this.currentTime, 0, 1, this.duration). Usually between 0 and 1, but not always (like with Elastic.easeOut, it could shoot past 1 or 0). **/ | ||
| 266 | public var ratio:Number = 0; | ||
| 267 | /** @private First PropTween instance - all of which are stored in a linked list for speed. Traverse them using nextNode and prevNode. Typically you should NOT use this property (it is made public for speed and file size purposes). **/ | ||
| 268 | public var cachedPT1:PropTween; | ||
| 269 | |||
| 270 | /** @private Easing method to use which determines how the values animate over time. Examples are Elastic.easeOut and Strong.easeIn. Many are found in the fl.motion.easing package or com.greensock.easing. **/ | ||
| 271 | protected var _ease:Function; | ||
| 272 | /** @private 0 = NONE, 1 = ALL, 2 = AUTO 3 = CONCURRENT, 4 = ALL_AFTER **/ | ||
| 273 | protected var _overwrite:uint; | ||
| 274 | /** @private When other tweens overwrite properties in this tween, the properties get added to this object. Remember, sometimes properties are overwritten BEFORE the tween inits, like when two tweens start at the same time, the later one overwrites the previous one. **/ | ||
| 275 | protected var _overwrittenProps:Object; | ||
| 276 | /** @private If this tween has any TweenPlugins, we set this to true - it helps speed things up in onComplete **/ | ||
| 277 | protected var _hasPlugins:Boolean; | ||
| 278 | /** @private If this tween has any TweenPlugins that need to be notified of a change in the "enabled" status, this will be true. (speeds things up in the enabled setter) **/ | ||
| 279 | protected var _notifyPluginsOfEnabled:Boolean; | ||
| 280 | |||
| 281 | |||
| 282 | /** | ||
| 283 | * Constructor | ||
| 284 | * | ||
| 285 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 286 | * @param duration Duration in seconds (or in frames if the tween's timing mode is frames-based) | ||
| 287 | * @param vars An object containing the end values of the properties you're tweening. For example, to tween to x=100, y=100, you could pass {x:100, y:100}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 288 | */ | ||
| 289 | public function TweenLite(target:Object, duration:Number, vars:Object) { | ||
| 290 | super(duration, vars); | ||
| 291 | this.target = target; | ||
| 292 | if (this.target is TweenCore && this.vars.timeScale) { //if timeScale is in the vars object and the target is a TweenCore, this tween's timeScale must be adjusted (in TweenCore's constructor, it was set to whatever the vars.timeScale was) | ||
| 293 | this.cachedTimeScale = 1; | ||
| 294 | } | ||
| 295 | propTweenLookup = {}; | ||
| 296 | _ease = defaultEase; //temporarily - we'll check the vars object for an ease property in the init() method. We set it to the default initially for speed purposes. | ||
| 297 | |||
| 298 | //handle overwriting (if necessary) on tweens of the same object and add the tween to the Dictionary for future reference. Also remember to accommodate TweenLiteVars and TweenMaxVars | ||
| 299 | _overwrite = (!(Number(vars.overwrite) > -1) || (!overwriteManager.enabled && vars.overwrite > 1)) ? overwriteManager.mode : int(vars.overwrite); | ||
| 300 | var a:Array = masterList[target]; | ||
| 301 | if (!a) { | ||
| 302 | masterList[target] = [this]; | ||
| 303 | } else { | ||
| 304 | if (_overwrite == 1) { //overwrite all other existing tweens of the same object (ALL mode) | ||
| 305 | for each (var sibling:TweenLite in a) { | ||
| 306 | if (!sibling.gc) { | ||
| 307 | sibling.setEnabled(false, false); | ||
| 308 | } | ||
| 309 | } | ||
| 310 | masterList[target] = [this]; | ||
| 311 | } else { | ||
| 312 | a[a.length] = this; | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 316 | if (this.active || this.vars.immediateRender) { | ||
| 317 | renderTime(0, false, true); | ||
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | /** | ||
| 322 | * @private | ||
| 323 | * Initializes the property tweens, determining their start values and amount of change. | ||
| 324 | * Also triggers overwriting if necessary and sets the _hasUpdate variable. | ||
| 325 | */ | ||
| 326 | protected function init():void { | ||
| 327 | if (this.vars.onInit) { | ||
| 328 | this.vars.onInit.apply(null, this.vars.onInitParams); | ||
| 329 | } | ||
| 330 | var p:String, i:int, plugin:*, prioritize:Boolean, siblings:Array; | ||
| 331 | if (typeof(this.vars.ease) == "function") { | ||
| 332 | _ease = this.vars.ease; | ||
| 333 | } | ||
| 334 | if (this.vars.easeParams) { | ||
| 335 | this.vars.proxiedEase = _ease; | ||
| 336 | _ease = easeProxy; | ||
| 337 | } | ||
| 338 | this.cachedPT1 = null; | ||
| 339 | this.propTweenLookup = {}; | ||
| 340 | for (p in this.vars) { | ||
| 341 | if (p in _reservedProps && !(p == "timeScale" && this.target is TweenCore)) { | ||
| 342 | //ignore | ||
| 343 | } else if (p in plugins && (plugin = new (plugins[p] as Class)()).onInitTween(this.target, this.vars[p], this)) { | ||
| 344 | this.cachedPT1 = new PropTween(plugin, | ||
| 345 | "changeFactor", | ||
| 346 | 0, | ||
| 347 | 1, | ||
| 348 | (plugin.overwriteProps.length == 1) ? plugin.overwriteProps[0] : "_MULTIPLE_", | ||
| 349 | true, | ||
| 350 | this.cachedPT1); | ||
| 351 | |||
| 352 | if (this.cachedPT1.name == "_MULTIPLE_") { | ||
| 353 | i = plugin.overwriteProps.length; | ||
| 354 | while (--i > -1) { | ||
| 355 | this.propTweenLookup[plugin.overwriteProps[i]] = this.cachedPT1; | ||
| 356 | } | ||
| 357 | } else { | ||
| 358 | this.propTweenLookup[this.cachedPT1.name] = this.cachedPT1; | ||
| 359 | } | ||
| 360 | if (plugin.priority) { | ||
| 361 | this.cachedPT1.priority = plugin.priority; | ||
| 362 | prioritize = true; | ||
| 363 | } | ||
| 364 | if (plugin.onDisable || plugin.onEnable) { | ||
| 365 | _notifyPluginsOfEnabled = true; | ||
| 366 | } | ||
| 367 | _hasPlugins = true; | ||
| 368 | |||
| 369 | } else { | ||
| 370 | this.cachedPT1 = new PropTween(this.target, | ||
| 371 | p, | ||
| 372 | Number(this.target[p]), | ||
| 373 | (typeof(this.vars[p]) == "number") ? Number(this.vars[p]) - this.target[p] : Number(this.vars[p]), | ||
| 374 | p, | ||
| 375 | false, | ||
| 376 | this.cachedPT1); | ||
| 377 | this.propTweenLookup[p] = this.cachedPT1; | ||
| 378 | } | ||
| 379 | |||
| 380 | } | ||
| 381 | if (prioritize) { | ||
| 382 | onPluginEvent("onInit", this); //reorders the linked list in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite | ||
| 383 | } | ||
| 384 | if (this.vars.runBackwards) { | ||
| 385 | var pt:PropTween = this.cachedPT1; | ||
| 386 | while (pt) { | ||
| 387 | pt.start += pt.change; | ||
| 388 | pt.change = -pt.change; | ||
| 389 | pt = pt.nextNode; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | _hasUpdate = Boolean(this.vars.onUpdate != null); | ||
| 393 | if (_overwrittenProps) { //another tween may have tried to overwrite properties of this tween before init() was called (like if two tweens start at the same time, the one created second will run first) | ||
| 394 | killVars(_overwrittenProps); | ||
| 395 | if (this.cachedPT1 == null) { //if all tweening properties have been overwritten, kill the tween. | ||
| 396 | this.setEnabled(false, false); | ||
| 397 | } | ||
| 398 | } | ||
| 399 | if (_overwrite > 1 && this.cachedPT1 && (siblings = masterList[this.target]) && siblings.length > 1) { | ||
| 400 | if (overwriteManager.manageOverwrites(this, this.propTweenLookup, siblings, _overwrite)) { | ||
| 401 | //one of the plugins had activeDisable set to true, so properties may have changed when it was disabled meaning we need to re-init() | ||
| 402 | init(); | ||
| 403 | } | ||
| 404 | } | ||
| 405 | this.initted = true; | ||
| 406 | } | ||
| 407 | |||
| 408 | /** @private **/ | ||
| 409 | override public function renderTime(time:Number, suppressEvents:Boolean=false, force:Boolean=false):void { | ||
| 410 | var isComplete:Boolean, prevTime:Number = this.cachedTime; | ||
| 411 | if (time >= this.cachedDuration) { | ||
| 412 | this.cachedTotalTime = this.cachedTime = this.cachedDuration; | ||
| 413 | this.ratio = 1; | ||
| 414 | isComplete = true; | ||
| 415 | if (this.cachedDuration == 0) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. | ||
| 416 | if ((time == 0 || _rawPrevTime < 0) && _rawPrevTime != time) { | ||
| 417 | force = true; | ||
| 418 | } | ||
| 419 | _rawPrevTime = time; | ||
| 420 | } | ||
| 421 | |||
| 422 | } else if (time <= 0) { | ||
| 423 | this.cachedTotalTime = this.cachedTime = this.ratio = 0; | ||
| 424 | if (time < 0) { | ||
| 425 | this.active = false; | ||
| 426 | if (this.cachedDuration == 0) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. | ||
| 427 | if (_rawPrevTime > 0) { | ||
| 428 | force = true; | ||
| 429 | isComplete = true; | ||
| 430 | } | ||
| 431 | _rawPrevTime = time; | ||
| 432 | } | ||
| 433 | } | ||
| 434 | if (this.cachedReversed && prevTime != 0) { | ||
| 435 | isComplete = true; | ||
| 436 | } | ||
| 437 | |||
| 438 | } else { | ||
| 439 | this.cachedTotalTime = this.cachedTime = time; | ||
| 440 | this.ratio = _ease(time, 0, 1, this.cachedDuration); | ||
| 441 | } | ||
| 442 | |||
| 443 | if (this.cachedTime == prevTime && !force) { | ||
| 444 | return; | ||
| 445 | } else if (!this.initted) { | ||
| 446 | init(); | ||
| 447 | if (!isComplete && this.cachedTime) { //_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently. | ||
| 448 | this.ratio = _ease(this.cachedTime, 0, 1, this.cachedDuration); | ||
| 449 | } | ||
| 450 | } | ||
| 451 | if (!this.active && !this.cachedPaused) { | ||
| 452 | this.active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. | ||
| 453 | } | ||
| 454 | if (prevTime == 0 && this.vars.onStart && this.cachedTime != 0 && !suppressEvents) { | ||
| 455 | this.vars.onStart.apply(null, this.vars.onStartParams); | ||
| 456 | } | ||
| 457 | |||
| 458 | var pt:PropTween = this.cachedPT1; | ||
| 459 | while (pt) { | ||
| 460 | pt.target[pt.property] = pt.start + (this.ratio * pt.change); | ||
| 461 | pt = pt.nextNode; | ||
| 462 | } | ||
| 463 | if (_hasUpdate && !suppressEvents) { | ||
| 464 | this.vars.onUpdate.apply(null, this.vars.onUpdateParams); | ||
| 465 | } | ||
| 466 | if (isComplete) { | ||
| 467 | if (_hasPlugins && this.cachedPT1) { | ||
| 468 | onPluginEvent("onComplete", this); | ||
| 469 | } | ||
| 470 | complete(true, suppressEvents); | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | /** | ||
| 475 | * Allows particular properties of the tween to be killed. For example, if a tween is affecting | ||
| 476 | * the "x", "y", and "alpha" properties and you want to kill just the "x" and "y" parts of the | ||
| 477 | * tween, you'd do <code>myTween.killVars({x:true, y:true});</code> | ||
| 478 | * | ||
| 479 | * @param vars An object containing a corresponding property for each one that should be killed. The values don't really matter. For example, to kill the x and y property tweens, do <code>myTween.killVars({x:true, y:true});</code> | ||
| 480 | * @param permanent If true, the properties specified in the vars object will be permanently disallowed in the tween. Typically the only time false might be used is while the tween is in the process of initting and a plugin needs to make sure tweens of a particular property (or set of properties) is killed. | ||
| 481 | * @return Boolean value indicating whether or not properties may have changed on the target when any of the vars were disabled. For example, when a motionBlur (plugin) is disabled, it swaps out a BitmapData for the target and may alter the alpha. We need to know this in order to determine whether or not a new tween that is overwriting this one should be re-initted() with the changed properties. | ||
| 482 | */ | ||
| 483 | public function killVars(vars:Object, permanent:Boolean=true):Boolean { | ||
| 484 | if (_overwrittenProps == null) { | ||
| 485 | _overwrittenProps = {}; | ||
| 486 | } | ||
| 487 | var p:String, pt:PropTween, changed:Boolean; | ||
| 488 | for (p in vars) { | ||
| 489 | if (p in propTweenLookup) { | ||
| 490 | pt = propTweenLookup[p]; | ||
| 491 | if (pt.isPlugin && pt.name == "_MULTIPLE_") { | ||
| 492 | pt.target.killProps(vars); | ||
| 493 | if (pt.target.overwriteProps.length == 0) { | ||
| 494 | pt.name = ""; | ||
| 495 | } | ||
| 496 | } | ||
| 497 | if (pt.name != "_MULTIPLE_") { | ||
| 498 | //remove PropTween (do it inline to improve speed and keep file size low) | ||
| 499 | if (pt.nextNode) { | ||
| 500 | pt.nextNode.prevNode = pt.prevNode; | ||
| 501 | } | ||
| 502 | if (pt.prevNode) { | ||
| 503 | pt.prevNode.nextNode = pt.nextNode; | ||
| 504 | } else if (this.cachedPT1 == pt) { | ||
| 505 | this.cachedPT1 = pt.nextNode; | ||
| 506 | } | ||
| 507 | if (pt.isPlugin && pt.target.onDisable) { | ||
| 508 | pt.target.onDisable(); //some plugins need to be notified so they can perform cleanup tasks first | ||
| 509 | if (pt.target.activeDisable) { | ||
| 510 | changed = true; | ||
| 511 | } | ||
| 512 | } | ||
| 513 | delete propTweenLookup[p]; | ||
| 514 | } | ||
| 515 | } | ||
| 516 | if (permanent && vars != _overwrittenProps) { | ||
| 517 | _overwrittenProps[p] = 1; | ||
| 518 | } | ||
| 519 | } | ||
| 520 | return changed; | ||
| 521 | } | ||
| 522 | |||
| 523 | /** @inheritDoc **/ | ||
| 524 | override public function invalidate():void { | ||
| 525 | if (_notifyPluginsOfEnabled && this.cachedPT1) { | ||
| 526 | onPluginEvent("onDisable", this); | ||
| 527 | } | ||
| 528 | this.cachedPT1 = null; | ||
| 529 | _overwrittenProps = null; | ||
| 530 | _hasUpdate = this.initted = this.active = _notifyPluginsOfEnabled = false; | ||
| 531 | this.propTweenLookup = {}; | ||
| 532 | } | ||
| 533 | |||
| 534 | /** @private **/ | ||
| 535 | override public function setEnabled(enabled:Boolean, ignoreTimeline:Boolean=false):Boolean { | ||
| 536 | if (enabled) { | ||
| 537 | var a:Array = TweenLite.masterList[this.target]; | ||
| 538 | if (!a) { | ||
| 539 | TweenLite.masterList[this.target] = [this]; | ||
| 540 | } else { | ||
| 541 | a[a.length] = this; | ||
| 542 | } | ||
| 543 | } | ||
| 544 | super.setEnabled(enabled, ignoreTimeline); | ||
| 545 | if (_notifyPluginsOfEnabled && this.cachedPT1) { | ||
| 546 | return onPluginEvent(((enabled) ? "onEnable" : "onDisable"), this); | ||
| 547 | } | ||
| 548 | return false; | ||
| 549 | } | ||
| 550 | |||
| 551 | |||
| 552 | //---- STATIC FUNCTIONS ----------------------------------------------------------------------------------- | ||
| 553 | |||
| 554 | /** | ||
| 555 | * Static method for creating a TweenLite instance. This can be more intuitive for some developers | ||
| 556 | * and shields them from potential garbage collection issues that could arise when assigning a | ||
| 557 | * tween instance to a variable that persists. The following lines of code produce exactly | ||
| 558 | * the same result: <br /><br /><code> | ||
| 559 | * | ||
| 560 | * var myTween:TweenLite = new TweenLite(mc, 1, {x:100}); <br /> | ||
| 561 | * TweenLite.to(mc, 1, {x:100}); <br /> | ||
| 562 | * var myTween:TweenLite = TweenLite.to(mc, 1, {x:100});</code> | ||
| 563 | * | ||
| 564 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 565 | * @param duration Duration in seconds (or in frames if the tween's timing mode is frames-based) | ||
| 566 | * @param vars An object containing the end values of the properties you're tweening. For example, to tween to x=100, y=100, you could pass {x:100, y:100}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 567 | * @return TweenLite instance | ||
| 568 | */ | ||
| 569 | public static function to(target:Object, duration:Number, vars:Object):TweenLite { | ||
| 570 | return new TweenLite(target, duration, vars); | ||
| 571 | } | ||
| 572 | |||
| 573 | /** | ||
| 574 | * Static method for creating a TweenLite instance that tweens in the opposite direction | ||
| 575 | * compared to a TweenLite.to() tween. In other words, you define the START values in the | ||
| 576 | * vars object instead of the end values, and the tween will use the current values as | ||
| 577 | * the end values. This can be very useful for animating things into place on the stage | ||
| 578 | * because you can build them in their end positions and do some simple TweenLite.from() | ||
| 579 | * calls to animate them into place. <b>NOTE:</b> By default, <code>immediateRender</code> | ||
| 580 | * is <code>true</code> in from() tweens, meaning that they immediately render their starting state | ||
| 581 | * regardless of any delay that is specified. You can override this behavior by passing | ||
| 582 | * <code>immediateRender:false</code> in the <code>vars</code> object so that it will wait to | ||
| 583 | * render until the tween actually begins (often the desired behavior when inserting into timelines). | ||
| 584 | * To illustrate the default behavior, the following code will immediately set the <code>alpha</code> of <code>mc</code> | ||
| 585 | * to 0 and then wait 2 seconds before tweening the <code>alpha</code> back to 1 over the course | ||
| 586 | * of 1.5 seconds:<br /><br /><code> | ||
| 587 | * | ||
| 588 | * TweenLite.from(mc, 1.5, {alpha:0, delay:2});</code> | ||
| 589 | * | ||
| 590 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 591 | * @param duration Duration in seconds (or in frames if the tween's timing mode is frames-based) | ||
| 592 | * @param vars An object containing the start values of the properties you're tweening. For example, to tween from x=100, y=100, you could pass {x:100, y:100}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 593 | * @return TweenLite instance | ||
| 594 | */ | ||
| 595 | public static function from(target:Object, duration:Number, vars:Object):TweenLite { | ||
| 596 | vars.runBackwards = true; | ||
| 597 | if (!("immediateRender" in vars)) { | ||
| 598 | vars.immediateRender = true; | ||
| 599 | } | ||
| 600 | return new TweenLite(target, duration, vars); | ||
| 601 | } | ||
| 602 | |||
| 603 | /** | ||
| 604 | * Provides a simple way to call a function after a set amount of time (or frames). You can | ||
| 605 | * optionally pass any number of parameters to the function too. For example:<br /><br /><code> | ||
| 606 | * | ||
| 607 | * TweenLite.delayedCall(1, myFunction, ["param1", 2]); <br /> | ||
| 608 | * function myFunction(param1:String, param2:Number):void { <br /> | ||
| 609 | * trace("called myFunction and passed params: " + param1 + ", " + param2); <br /> | ||
| 610 | * } </code> | ||
| 611 | * | ||
| 612 | * @param delay Delay in seconds (or frames if useFrames is true) before the function should be called | ||
| 613 | * @param onComplete Function to call | ||
| 614 | * @param onCompleteParams An Array of parameters to pass the function. | ||
| 615 | * @param useFrames If the delay should be measured in frames instead of seconds, set useFrames to true (default is false) | ||
| 616 | * @return TweenLite instance | ||
| 617 | */ | ||
| 618 | public static function delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array=null, useFrames:Boolean=false):TweenLite { | ||
| 619 | return new TweenLite(onComplete, 0, {delay:delay, onComplete:onComplete, onCompleteParams:onCompleteParams, immediateRender:false, useFrames:useFrames, overwrite:0}); | ||
| 620 | } | ||
| 621 | |||
| 622 | /** | ||
| 623 | * @private | ||
| 624 | * Updates the rootTimeline and rootFramesTimeline and collects garbage every 60 frames. | ||
| 625 | * | ||
| 626 | * @param e ENTER_FRAME Event | ||
| 627 | */ | ||
| 628 | protected static function updateAll(e:Event = null):void { | ||
| 629 | rootTimeline.renderTime(((getTimer() * 0.001) - rootTimeline.cachedStartTime) * rootTimeline.cachedTimeScale, false, false); | ||
| 630 | rootFrame++; | ||
| 631 | rootFramesTimeline.renderTime((rootFrame - rootFramesTimeline.cachedStartTime) * rootFramesTimeline.cachedTimeScale, false, false); | ||
| 632 | |||
| 633 | if (!(rootFrame % 60)) { //garbage collect every 60 frames... | ||
| 634 | var ml:Dictionary = masterList, tgt:Object, a:Array, i:int; | ||
| 635 | for (tgt in ml) { | ||
| 636 | a = ml[tgt]; | ||
| 637 | i = a.length; | ||
| 638 | while (--i > -1) { | ||
| 639 | if (TweenLite(a[i]).gc) { | ||
| 640 | a.splice(i, 1); | ||
| 641 | } | ||
| 642 | } | ||
| 643 | if (a.length == 0) { | ||
| 644 | delete ml[tgt]; | ||
| 645 | } | ||
| 646 | } | ||
| 647 | } | ||
| 648 | |||
| 649 | } | ||
| 650 | |||
| 651 | |||
| 652 | /** | ||
| 653 | * Kills all the tweens (or certain tweening properties) of a particular object, optionally completing them first. | ||
| 654 | * If, for example, you want to kill all tweens of the "mc" object, you'd do:<br /><br /><code> | ||
| 655 | * | ||
| 656 | * TweenLite.killTweensOf(mc);<br /><br /></code> | ||
| 657 | * | ||
| 658 | * But if you only want to kill all the "alpha" and "x" portions of mc's tweens, you'd do:<br /><br /><code> | ||
| 659 | * | ||
| 660 | * TweenLite.killTweensOf(mc, false, {alpha:true, x:true});<br /><br /></code> | ||
| 661 | * | ||
| 662 | * <code>killTweensOf()</code> affects tweens that haven't begun yet too. If, for example, | ||
| 663 | * a tween of object "mc" has a delay of 5 seconds and <code>TweenLite.killTweensOf(mc)</code> is called | ||
| 664 | * 2 seconds after the tween was created, it will still be killed even though it hasn't started yet. <br /><br /> | ||
| 665 | * | ||
| 666 | * @param target Object whose tweens should be immediately killed | ||
| 667 | * @param complete Indicates whether or not the tweens should be forced to completion before being killed. | ||
| 668 | * @param vars An object defining which tweening properties should be killed (null causes all properties to be killed). For example, if you only want to kill "alpha" and "x" tweens of object "mc", you'd do <code>myTimeline.killTweensOf(mc, true, {alpha:true, x:true})</code>. If there are no tweening properties remaining in a tween after the indicated properties are killed, the entire tween is killed, meaning any onComplete, onUpdate, onStart, etc. won't fire. | ||
| 669 | */ | ||
| 670 | public static function killTweensOf(target:Object, complete:Boolean=false, vars:Object=null):void { | ||
| 671 | if (target in masterList) { | ||
| 672 | var a:Array = masterList[target]; | ||
| 673 | var i:int = a.length; | ||
| 674 | var tween:TweenLite; | ||
| 675 | while (--i > -1) { | ||
| 676 | tween = a[i]; | ||
| 677 | if (!tween.gc) { | ||
| 678 | if (complete) { | ||
| 679 | tween.complete(false, false); | ||
| 680 | } | ||
| 681 | if (vars != null) { | ||
| 682 | tween.killVars(vars); | ||
| 683 | } | ||
| 684 | if (vars == null || (tween.cachedPT1 == null && tween.initted)) { | ||
| 685 | tween.setEnabled(false, false); | ||
| 686 | } | ||
| 687 | } | ||
| 688 | } | ||
| 689 | if (vars == null) { | ||
| 690 | delete masterList[target]; | ||
| 691 | } | ||
| 692 | } | ||
| 693 | } | ||
| 694 | |||
| 695 | /** | ||
| 696 | * @private | ||
| 697 | * Default easing equation | ||
| 698 | * | ||
| 699 | * @param t time | ||
| 700 | * @param b start (must always be 0) | ||
| 701 | * @param c change (must always be 1) | ||
| 702 | * @param d duration | ||
| 703 | * @return Eased value | ||
| 704 | */ | ||
| 705 | protected static function easeOut(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 706 | return 1 - (t = 1 - (t / d)) * t; | ||
| 707 | } | ||
| 708 | |||
| 709 | /** | ||
| 710 | * @private | ||
| 711 | * Only used for easing equations that accept extra parameters (like Elastic.easeOut and Back.easeOut). | ||
| 712 | * Basically, it acts as a proxy. To utilize it, pass an Array of extra parameters via the vars object's | ||
| 713 | * "easeParams" special property | ||
| 714 | * | ||
| 715 | * @param t time | ||
| 716 | * @param b start | ||
| 717 | * @param c change | ||
| 718 | * @param d duration | ||
| 719 | * @return Eased value | ||
| 720 | */ | ||
| 721 | protected function easeProxy(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 722 | return this.vars.proxiedEase.apply(null, arguments.concat(this.vars.easeParams)); | ||
| 723 | } | ||
| 724 | |||
| 725 | |||
| 726 | } | ||
| 727 | |||
| 728 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 11.37 | ||
| 3 | * DATE: 2010-05-14 | ||
| 4 | * AS3 (AS2 version is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock { | ||
| 8 | import com.greensock.core.*; | ||
| 9 | import com.greensock.events.TweenEvent; | ||
| 10 | import com.greensock.plugins.*; | ||
| 11 | |||
| 12 | import flash.display.*; | ||
| 13 | import flash.events.*; | ||
| 14 | import flash.utils.*; | ||
| 15 | /** | ||
| 16 | * TweenMax extends the extremely lightweight, fast TweenLite engine, adding many useful features | ||
| 17 | * like timeScale, event dispatching, updateTo(), yoyo, repeat, repeatDelay, rounding, and more. It also | ||
| 18 | * activates many extra plugins by default, making it extremely full-featured. Since TweenMax extends | ||
| 19 | * TweenLite, it can do ANYTHING TweenLite can do plus much more. The syntax is identical. With plenty | ||
| 20 | * of other tweening engines to choose from, here's why you might want to consider TweenMax: | ||
| 21 | * | ||
| 22 | * <ul> | ||
| 23 | * <li><b> SPEED </b>- TweenMax has been highly optimized for maximum performance. See some speed comparisons yourself at | ||
| 24 | * <a href="http://www.greensock.com/tweening-speed-test/">http://www.greensock.com/tweening-speed-test/</a></li> | ||
| 25 | * | ||
| 26 | * <li><b> Feature set </b>- In addition to tweening ANY numeric property of ANY object, TweenMax can tween filters, | ||
| 27 | * hex colors, volume, tint, frames, saturation, contrast, hue, colorization, brightness, and even do | ||
| 28 | * bezier tweening, orientToBezier, round values, jump to any point in the tween with the <code>currentTime</code> | ||
| 29 | * or <code>currentProgress</code> property, automatically rotate in the shortest direction, plus LOTS more. | ||
| 30 | * Overwrite management is an important consideration for a tweening engine as well which is another area | ||
| 31 | * where the GreenSock Tweening Platform shines. You have options for AUTO overwriting or you can manually | ||
| 32 | * define how each tween will handle overlapping tweens of the same object.</li> | ||
| 33 | * | ||
| 34 | * <li><b> Expandability </b>- With its plugin architecture, you can activate as many (or as few) features as your | ||
| 35 | * project requires. Write your own plugin to handle particular special properties in custom ways. Minimize bloat, and | ||
| 36 | * maximize performance.</li> | ||
| 37 | * | ||
| 38 | * <li><b> Sequencing, grouping, and management features </b>- TimelineLite and TimelineMax make it surprisingly | ||
| 39 | * simple to create complex sequences or groups of tweens that you can control as a whole. play(), pause(), restart(), | ||
| 40 | * or reverse(). You can even tween a timeline's <code>currentTime</code> or <code>currentProgress</code> property | ||
| 41 | * to fastforward or rewind the entire timeline. Add labels, gotoAndPlay(), change the timeline's timeScale, nest | ||
| 42 | * timelines within timelines, and lots more.</li> | ||
| 43 | * | ||
| 44 | * <li><b> Ease of use </b>- Designers and Developers alike rave about how intuitive the platform is.</li> | ||
| 45 | * | ||
| 46 | * <li><b> Updates </b>- Frequent updates and feature additions make the GreenSock Tweening Platform reliable and robust.</li> | ||
| 47 | * | ||
| 48 | * <li><b> AS2 and AS3 </b>- Most other engines are only developed for AS2 or AS3 but not both.</li> | ||
| 49 | * </ul> | ||
| 50 | * | ||
| 51 | * <b>SPECIAL PROPERTIES (no plugins required):</b><br /><br /> | ||
| 52 | * | ||
| 53 | * Any of the following special properties can optionally be passed in through the vars object (the third parameter): | ||
| 54 | * <ul> | ||
| 55 | * <li><b> delay : Number</b> Amount of delay in seconds (or frames for frames-based tweens) before the tween should begin.</li> | ||
| 56 | * | ||
| 57 | * <li><b> useFrames : Boolean</b> If useFrames is set to true, the tweens's timing mode will be based on frames. | ||
| 58 | * Otherwise, it will be based on seconds/time. NOTE: a tween's timing mode is | ||
| 59 | * always determined by its parent timeline. </li> | ||
| 60 | * | ||
| 61 | * <li><b> ease : Function</b> Use any standard easing equation to control the rate of change. For example, | ||
| 62 | * Elastic.easeOut. The Default is Quad.easeOut.</li> | ||
| 63 | * | ||
| 64 | * <li><b> easeParams : Array</b> An Array of extra parameters to feed the easing equation (beyond the standard first 4). | ||
| 65 | * This can be useful when using an ease like Elastic and want to control extra parameters | ||
| 66 | * like the amplitude and period. Most easing equations, however, don't require extra parameters | ||
| 67 | * so you won't need to pass in any easeParams.</li> | ||
| 68 | * | ||
| 69 | * <li><b> onInit : Function</b> A function that should be called just before the tween inits (renders for the first time). | ||
| 70 | * Since onInit runs before the start/end values are recorded internally, it is a good place to run | ||
| 71 | * code that affects the target's initial position or other tween-related properties. onStart, by | ||
| 72 | * contrast, runs AFTER the tween inits and the start/end values are recorded internally. onStart | ||
| 73 | * is called every time the tween begins which can happen more than once if the tween is restarted | ||
| 74 | * multiple times.</li> | ||
| 75 | * | ||
| 76 | * <li><b> onInitParams : Array</b> An Array of parameters to pass the onInit function.</li> | ||
| 77 | * | ||
| 78 | * <li><b> onStart : Function</b> A function that should be called when the tween begins (when its currentTime is at 0 and | ||
| 79 | * changes to some other value which can happen more than once if the tween is restarted multiple times).</li> | ||
| 80 | * | ||
| 81 | * <li><b> onStartParams : Array</b> An Array of parameters to pass the onStart function.</li> | ||
| 82 | * | ||
| 83 | * <li><b> onUpdate : Function</b> A function that should be called every time the tween's time/position is updated | ||
| 84 | * (on every frame while the timeline is active)</li> | ||
| 85 | * | ||
| 86 | * <li><b> onUpdateParams : Array</b> An Array of parameters to pass the onUpdate function</li> | ||
| 87 | * | ||
| 88 | * <li><b> onComplete : Function</b> A function that should be called when the tween has finished </li> | ||
| 89 | * | ||
| 90 | * <li><b> onCompleteParams : Array</b> An Array of parameters to pass the onComplete function</li> | ||
| 91 | * | ||
| 92 | * <li><b> onReverseComplete : Function</b> A function that should be called when the tween has reached its starting point again after having been reversed. </li> | ||
| 93 | * | ||
| 94 | * <li><b> onReverseCompleteParams : Array</b> An Array of parameters to pass the onReverseComplete function.</li> | ||
| 95 | * | ||
| 96 | * <li><b> onRepeat : Function</b> A function that should be called every time the tween repeats </li> | ||
| 97 | * | ||
| 98 | * <li><b> onRepeatParams : Array</b> An Array of parameters to pass the onRepeat function</li> | ||
| 99 | * | ||
| 100 | * <li><b> immediateRender : Boolean</b> Normally when you create a tween, it begins rendering on the very next frame (when | ||
| 101 | * the Flash Player dispatches an ENTER_FRAME event) unless you specify a <code>delay</code>. This | ||
| 102 | * allows you to insert tweens into timelines and perform other actions that may affect | ||
| 103 | * its timing. However, if you prefer to force the tween to render immediately when it is | ||
| 104 | * created, set <code>immediateRender</code> to true. Or to prevent a tween with a duration of zero from | ||
| 105 | * rendering immediately, set this to false.</li> | ||
| 106 | * | ||
| 107 | * <li><b> paused : Boolean</b> If true, the tween will be paused initially.</li> | ||
| 108 | * | ||
| 109 | * <li><b> reversed : Boolean</b> If true, the tween will be reversed initially. This does not swap the starting/ending | ||
| 110 | * values in the tween - it literally changes its orientation/direction. Imagine the playhead | ||
| 111 | * moving backwards instead of forwards. This does NOT force it to the very end and start | ||
| 112 | * playing backwards. It simply affects the orientation of the tween, so if reversed is set to | ||
| 113 | * true initially, it will appear not to play because it is already at the beginning. To cause it to | ||
| 114 | * play backwards from the end, set reversed to true and then set the <code>currentProgress</code> | ||
| 115 | * property to 1 immediately after creating the tween (or set the currentTime to the duration). </li> | ||
| 116 | * | ||
| 117 | * <li><b> overwrite : int</b> Controls how (and if) other tweens of the same target are overwritten by this tween. There are | ||
| 118 | * several modes to choose from, and TweenMax automatically calls <code>OverwriteManager.init()</code> if you haven't | ||
| 119 | * already manually dones so, which means that by default <code>AUTO</code> mode is used (please see | ||
| 120 | * <a href="http://www.greensock.com/overwritemanager/">http://www.greensock.com/overwritemanager/</a> | ||
| 121 | * for details and a full explanation of the various modes): | ||
| 122 | * <ul> | ||
| 123 | * <li>NONE (0) (or false) </li> | ||
| 124 | * | ||
| 125 | * <li>ALL_IMMEDIATE (1) (or true)</li> | ||
| 126 | * | ||
| 127 | * <li>AUTO (2) - this is the default mode for TweenMax.</li> | ||
| 128 | * | ||
| 129 | * <li>CONCURRENT (3)</li> | ||
| 130 | * | ||
| 131 | * <li>ALL_ONSTART (4)</li> | ||
| 132 | * | ||
| 133 | * <li>PREEXISTING (5)</li> | ||
| 134 | * | ||
| 135 | * </ul></li> | ||
| 136 | * | ||
| 137 | * <li><b> repeat : int</b> Number of times that the tween should repeat. To repeat indefinitely, use -1.</li> | ||
| 138 | * | ||
| 139 | * <li><b> repeatDelay : Number</b> Amount of time in seconds (or frames for frames-based tween) between repeats.</li> | ||
| 140 | * | ||
| 141 | * <li><b> yoyo : Boolean</b> Works in conjunction with the repeat property, determining the behavior of each | ||
| 142 | * cycle. When yoyo is true, the tween will go back and forth, appearing to reverse | ||
| 143 | * every other cycle (this has no affect on the "reversed" property though). So if repeat is | ||
| 144 | * 2 and yoyo is false, it will look like: start - 1 - 2 - 3 - 1 - 2 - 3 - 1 - 2 - 3 - end. But | ||
| 145 | * if repeat is 2 and yoyo is true, it will look like: start - 1 - 2 - 3 - 3 - 2 - 1 - 1 - 2 - 3 - end. </li> | ||
| 146 | * | ||
| 147 | * <li><b> onStartListener : Function</b> A function to which the TweenMax instance should dispatch a TweenEvent when it begins. | ||
| 148 | * This is the same as doing <code>myTween.addEventListener(TweenEvent.START, myFunction);</code></li> | ||
| 149 | * | ||
| 150 | * <li><b> onUpdateListener : Function</b> A function to which the TweenMax instance should dispatch a TweenEvent every time it | ||
| 151 | * updates values. This is the same as doing <code>myTween.addEventListener(TweenEvent.UPDATE, myFunction);</code></li> | ||
| 152 | * | ||
| 153 | * <li><b> onCompleteListener : Function</b> A function to which the TweenMax instance should dispatch a TweenEvent when it completes. | ||
| 154 | * This is the same as doing <code>myTween.addEventListener(TweenEvent.COMPLETE, myFunction);</code></li> | ||
| 155 | * | ||
| 156 | * <li><b> onReverseCompleteListener : Function</b> A function to which the TweenMax instance should dispatch a TweenEvent when it completes | ||
| 157 | * in the reverse direction. This is the same as doing <code>myTween.addEventListener(TweenEvent.REVERSE_COMPLETE, myFunction);</code></li> | ||
| 158 | * | ||
| 159 | * <li><b> onRepeatListener : Function</b> A function to which the TweenMax instance should dispatch a TweenEvent when it repeats. | ||
| 160 | * This is the same as doing <code>myTween.addEventListener(TweenEvent.REPEAT, myFunction);</code></li> | ||
| 161 | * | ||
| 162 | * <li><b> startAt : Object</b> Allows you to define the starting values for each property. Typically, TweenMax uses the current | ||
| 163 | * value (whatever it happens to be at the time the tween begins) as the start value, but startAt | ||
| 164 | * allows you to override that behavior. Simply pass an object in with whatever properties you'd like | ||
| 165 | * to set just before the tween begins. For example, if mc.x is currently 100, and you'd like to | ||
| 166 | * tween it from 0 to 500, do <code>TweenMax.to(mc, 2, {x:500, startAt:{x:0}});</code> </li> | ||
| 167 | * </ul> | ||
| 168 | * | ||
| 169 | * <b>PLUGINS: </b><br /><br /> | ||
| 170 | * | ||
| 171 | * There are many plugins that add capabilities through other special properties. Adding the capabilities | ||
| 172 | * is as simple as activating the plugin with a single line of code, like <code>TweenPlugin.activate([SetSizePlugin]);</code> | ||
| 173 | * Get information about all the plugins at <a href="http://www.TweenMax.com">http://www.TweenMax.com</a>. The | ||
| 174 | * following plugins are activated by default in TweenMax (you can easily prevent them from activating, thus | ||
| 175 | * saving file size, by commenting out the associated activation lines towards the top of the class): | ||
| 176 | * | ||
| 177 | * <ul> | ||
| 178 | * <li><b> autoAlpha : Number</b> - Use it instead of the alpha property to gain the additional feature of toggling | ||
| 179 | * the visible property to false when alpha reaches 0. It will also toggle visible | ||
| 180 | * to true before the tween starts if the value of autoAlpha is greater than zero.</li> | ||
| 181 | * | ||
| 182 | * <li><b> visible : Boolean</b> - To set a DisplayObject's "visible" property at the end of the tween, use this special property.</li> | ||
| 183 | * | ||
| 184 | * <li><b> volume : Number</b> - Tweens the volume of an object with a soundTransform property (MovieClip/SoundChannel/NetStream, etc.)</li> | ||
| 185 | * | ||
| 186 | * <li><b> tint : Number</b> - To change a DisplayObject's tint/color, set this to the hex value of the tint you'd like | ||
| 187 | * to end up at(or begin at if you're using TweenMax.from()). An example hex value would be 0xFF0000.</li> | ||
| 188 | * | ||
| 189 | * <li><b> removeTint : Boolean</b> - If you'd like to remove the tint that's applied to a DisplayObject, pass true for this special property.</li> | ||
| 190 | * | ||
| 191 | * <li><b> frame : Number</b> - Use this to tween a MovieClip to a particular frame.</li> | ||
| 192 | * | ||
| 193 | * <li><b> bezier : Array</b> - Bezier tweening allows you to tween in a non-linear way. For example, you may want to tween | ||
| 194 | * a MovieClip's position from the origin (0,0) 500 pixels to the right (500,0) but curve downwards | ||
| 195 | * through the middle of the tween. Simply pass as many objects in the bezier array as you'd like, | ||
| 196 | * one for each "control point" (see documentation on Flash's curveTo() drawing method for more | ||
| 197 | * about how control points work). In this example, let's say the control point would be at x/y coordinates | ||
| 198 | * 250,50. Just make sure your my_mc is at coordinates 0,0 and then do: | ||
| 199 | * <code>TweenMax.to(my_mc, 3, {bezier:[{x:250, y:50}, {x:500, y:0}]});</code></li> | ||
| 200 | * | ||
| 201 | * <li><b> bezierThrough : Array</b> - Identical to bezier except that instead of passing bezier control point values, you | ||
| 202 | * pass points through which the bezier values should move. This can be more intuitive | ||
| 203 | * than using control points.</li> | ||
| 204 | * | ||
| 205 | * <li><b> orientToBezier : Array (or Boolean)</b> - A common effect that designers/developers want is for a MovieClip/Sprite to | ||
| 206 | * orient itself in the direction of a Bezier path (alter its rotation). orientToBezier | ||
| 207 | * makes it easy. In order to alter a rotation property accurately, TweenMax needs 4 pieces | ||
| 208 | * of information: | ||
| 209 | * <ol> | ||
| 210 | * <li> Position property 1 (typically "x")</li> | ||
| 211 | * <li> Position property 2 (typically "y")</li> | ||
| 212 | * <li> Rotational property (typically "rotation")</li> | ||
| 213 | * <li> Number of degrees to add (optional - makes it easy to orient your MovieClip properly)</li> | ||
| 214 | * </ol> | ||
| 215 | * The orientToBezier property should be an Array containing one Array for each set of these values. | ||
| 216 | * For maximum flexibility, you can pass in any number of arrays inside the container array, one | ||
| 217 | * for each rotational property. This can be convenient when working in 3D because you can rotate | ||
| 218 | * on multiple axis. If you're doing a standard 2D x/y tween on a bezier, you can simply pass | ||
| 219 | * in a boolean value of true and TweenMax will use a typical setup, <code>[["x", "y", "rotation", 0]]</code>. | ||
| 220 | * Hint: Don't forget the container Array (notice the double outer brackets)</li> | ||
| 221 | * | ||
| 222 | * <li><b> hexColors : Object</b> - Although hex colors are technically numbers, if you try to tween them conventionally, | ||
| 223 | * you'll notice that they don't tween smoothly. To tween them properly, the red, green, and | ||
| 224 | * blue components must be extracted and tweened independently. TweenMax makes it easy. To tween | ||
| 225 | * a property of your object that's a hex color to another hex color, use this special hexColors | ||
| 226 | * property of TweenMax. It must be an OBJECT with properties named the same as your object's | ||
| 227 | * hex color properties. For example, if your my_obj object has a "myHexColor" property that you'd like | ||
| 228 | * to tween to red (0xFF0000) over the course of 2 seconds, do: <br /> | ||
| 229 | * <code>TweenMax.to(my_obj, 2, {hexColors:{myHexColor:0xFF0000}});</code><br /> | ||
| 230 | * You can pass in any number of hexColor properties.</li> | ||
| 231 | * | ||
| 232 | * <li><b> shortRotation : Object</b> - To tween the rotation property of the target object in the shortest direction, use "shortRotation" | ||
| 233 | * instead of "rotation" as the property. For example, if <code>myObject.rotation</code> is currently 170 degrees | ||
| 234 | * and you want to tween it to -170 degrees, a normal rotation tween would travel a total of 340 degrees | ||
| 235 | * in the counter-clockwise direction, but if you use shortRotation, it would travel 20 degrees in the | ||
| 236 | * clockwise direction instead.</li> | ||
| 237 | * | ||
| 238 | * <li><b> roundProps : Array</b> - If you'd like the inbetween values in a tween to always get rounded to the nearest integer, use the roundProps | ||
| 239 | * special property. Just pass in an Array containing the property names that you'd like rounded. For example, | ||
| 240 | * if you're tweening the x, y, and alpha properties of mc and you want to round the x and y values (not alpha) | ||
| 241 | * every time the tween is rendered, you'd do: <code>TweenMax.to(mc, 2, {x:300, y:200, alpha:0.5, roundProps:["x","y"]});</code></li> | ||
| 242 | * | ||
| 243 | * <li><b> blurFilter : Object</b> - To apply a BlurFilter, pass an object with one or more of the following properties: | ||
| 244 | * <code>blurX, blurY, quality, remove, addFilter, index</code></li> | ||
| 245 | * | ||
| 246 | * <li><b> glowFilter : Object</b> - To apply a GlowFilter, pass an object with one or more of the following properties: | ||
| 247 | * <code>alpha, blurX, blurY, color, strength, quality, inner, knockout, remove, addFilter, index</code></li> | ||
| 248 | * | ||
| 249 | * <li><b> colorMatrixFilter : Object</b> - To apply a ColorMatrixFilter, pass an object with one or more of the following properties: | ||
| 250 | * <code>colorize, amount, contrast, brightness, saturation, hue, threshold, relative, matrix, remove, addFilter, index</code></li> | ||
| 251 | * | ||
| 252 | * <li><b> dropShadowFilter : Object</b> - To apply a DropShadowFilter, pass an object with one or more of the following properties: | ||
| 253 | * <code>alpha, angle, blurX, blurY, color, distance, strength, quality, remove, addFilter, index</code></li> | ||
| 254 | * | ||
| 255 | * <li><b> bevelFilter : Object</b> - To apply a BevelFilter, pass an object with one or more of the following properties: | ||
| 256 | * <code>angle, blurX, blurY, distance, highlightAlpha, highlightColor, shadowAlpha, shadowColor, strength, quality, remove, addFilter, index</code></li> | ||
| 257 | * </ul> | ||
| 258 | * | ||
| 259 | * | ||
| 260 | * <b>EXAMPLES:</b><br /><br /> | ||
| 261 | * | ||
| 262 | * Please see <a href="http://www.tweenmax.com">http://www.tweenmax.com</a> for examples, tutorials, and interactive demos. <br /><br /> | ||
| 263 | * | ||
| 264 | * <b>NOTES / TIPS:</b> | ||
| 265 | * <ul> | ||
| 266 | * <li> Passing values as Strings will make the tween relative to the current value. For example, if you do | ||
| 267 | * <code>TweenMax.to(mc, 2, {x:"-20"});</code> it'll move the mc.x to the left 20 pixels which is the same as doing | ||
| 268 | * <code>TweenMax.to(mc, 2, {x:mc.x - 20});</code> You could also cast it like: <code>TweenMax.to(mc, 2, {x:String(myVariable)});</code></li> | ||
| 269 | * | ||
| 270 | * <li> If you prefer, instead of using the onCompleteListener, onInitListener, onStartListener, and onUpdateListener special properties, | ||
| 271 | * you can set up listeners the typical way, like:<br /><code> | ||
| 272 | * var myTween:TweenMax = new TweenMax(my_mc, 2, {x:200});<br /> | ||
| 273 | * myTween.addEventListener(TweenEvent.COMPLETE, myFunction);</code></li> | ||
| 274 | * | ||
| 275 | * <li> You can kill all tweens of a particular object anytime with the <code>TweenMax.killTweensOf(myObject); </code></li> | ||
| 276 | * | ||
| 277 | * <li> You can kill all delayedCalls to a particular function using <code>TweenMax.killDelayedCallsTo(myFunction);</code> | ||
| 278 | * This can be helpful if you want to preempt a call.</li> | ||
| 279 | * | ||
| 280 | * <li> Use the <code>TweenMax.from()</code> method to animate things into place. For example, if you have things set up on | ||
| 281 | * the stage in the spot where they should end up, and you just want to animate them into place, you can | ||
| 282 | * pass in the beginning x and/or y and/or alpha (or whatever properties you want).</li> | ||
| 283 | * | ||
| 284 | * <li> If you find this class useful, please consider joining Club GreenSock which not only helps to sustain | ||
| 285 | * ongoing development, but also gets you bonus plugins, classes and other benefits that are ONLY available | ||
| 286 | * to members. Learn more at <a href="http://www.greensock.com/club/">http://www.greensock.com/club/</a></li> | ||
| 287 | * </ul> | ||
| 288 | * | ||
| 289 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 290 | * | ||
| 291 | * @author Jack Doyle, jack@greensock.com | ||
| 292 | */ | ||
| 293 | public class TweenMax extends TweenLite implements IEventDispatcher { | ||
| 294 | /** @private **/ | ||
| 295 | public static const version:Number = 11.37; | ||
| 296 | |||
| 297 | TweenPlugin.activate([ | ||
| 298 | |||
| 299 | |||
| 300 | //ACTIVATE (OR DEACTIVATE) PLUGINS HERE... | ||
| 301 | |||
| 302 | AutoAlphaPlugin, //tweens alpha and then toggles "visible" to false if/when alpha is zero | ||
| 303 | EndArrayPlugin, //tweens numbers in an Array | ||
| 304 | FramePlugin, //tweens MovieClip frames | ||
| 305 | RemoveTintPlugin, //allows you to remove a tint | ||
| 306 | TintPlugin, //tweens tints | ||
| 307 | VisiblePlugin, //tweens a target's "visible" property | ||
| 308 | VolumePlugin, //tweens the volume of a MovieClip or SoundChannel or anything with a "soundTransform" property | ||
| 309 | |||
| 310 | BevelFilterPlugin, //tweens BevelFilters | ||
| 311 | BezierPlugin, //enables bezier tweening | ||
| 312 | BezierThroughPlugin, //enables bezierThrough tweening | ||
| 313 | BlurFilterPlugin, //tweens BlurFilters | ||
| 314 | ColorMatrixFilterPlugin, //tweens ColorMatrixFilters (including hue, saturation, colorize, contrast, brightness, and threshold) | ||
| 315 | ColorTransformPlugin, //tweens advanced color properties like exposure, brightness, tintAmount, redOffset, redMultiplier, etc. | ||
| 316 | DropShadowFilterPlugin, //tweens DropShadowFilters | ||
| 317 | FrameLabelPlugin, //tweens a MovieClip to particular label | ||
| 318 | GlowFilterPlugin, //tweens GlowFilters | ||
| 319 | HexColorsPlugin, //tweens hex colors | ||
| 320 | RoundPropsPlugin, //enables the roundProps special property for rounding values (ONLY for TweenMax!) | ||
| 321 | ShortRotationPlugin, //tweens rotation values in the shortest direction | ||
| 322 | |||
| 323 | //QuaternionsPlugin, //tweens 3D Quaternions | ||
| 324 | //ScalePlugin, //Tweens both the _xscale and _yscale properties | ||
| 325 | //ScrollRectPlugin, //tweens the scrollRect property of a DisplayObject | ||
| 326 | //SetSizePlugin, //tweens the width/height of components via setSize() | ||
| 327 | //SetActualSizePlugin, //tweens the width/height of components via setActualSize() | ||
| 328 | //TransformMatrixPlugin, //Tweens the transform.matrix property of any DisplayObject | ||
| 329 | |||
| 330 | //DynamicPropsPlugin, //tweens to dynamic end values. You associate the property with a particular function that returns the target end value **Club GreenSock membership benefit** | ||
| 331 | //MotionBlurPlugin, //applies a directional blur to a DisplayObject based on the velocity and angle of movement. **Club GreenSock membership benefit** | ||
| 332 | //Physics2DPlugin, //allows you to apply basic physics in 2D space, like velocity, angle, gravity, friction, acceleration, and accelerationAngle. **Club GreenSock membership benefit** | ||
| 333 | //PhysicsPropsPlugin, //allows you to apply basic physics to any property using forces like velocity, acceleration, and/or friction. **Club GreenSock membership benefit** | ||
| 334 | //TransformAroundCenterPlugin,//tweens the scale and/or rotation of DisplayObjects using the DisplayObject's center as the registration point **Club GreenSock membership benefit** | ||
| 335 | //TransformAroundPointPlugin, //tweens the scale and/or rotation of DisplayObjects around a particular point (like a custom registration point) **Club GreenSock membership benefit** | ||
| 336 | |||
| 337 | |||
| 338 | {}]); //activated in static var instead of constructor because otherwise if there's a from() tween, TweenLite's constructor would get called first and initTweenVals() would run before the plugins were activated. | ||
| 339 | |||
| 340 | |||
| 341 | /** @private Just to make sure OverwriteManager is activated. **/ | ||
| 342 | private static var _overwriteMode:int = (OverwriteManager.enabled) ? OverwriteManager.mode : OverwriteManager.init(2); | ||
| 343 | |||
| 344 | /** | ||
| 345 | * Kills all the tweens of a particular object, optionally completing them first. | ||
| 346 | * | ||
| 347 | * @param target Object whose tweens should be immediately killed | ||
| 348 | * @param complete Indicates whether or not the tweens should be forced to completion before being killed. | ||
| 349 | */ | ||
| 350 | public static var killTweensOf:Function = TweenLite.killTweensOf; | ||
| 351 | /** @private **/ | ||
| 352 | public static var killDelayedCallsTo:Function = TweenLite.killTweensOf; | ||
| 353 | /** @private **/ | ||
| 354 | protected var _dispatcher:EventDispatcher; | ||
| 355 | /** @private **/ | ||
| 356 | protected var _hasUpdateListener:Boolean; | ||
| 357 | /** @private **/ | ||
| 358 | protected var _repeat:int = 0; | ||
| 359 | /** @private **/ | ||
| 360 | protected var _repeatDelay:Number = 0; | ||
| 361 | /** @private **/ | ||
| 362 | protected var _cyclesComplete:uint = 0; | ||
| 363 | /** @private Indicates the strength of the fast ease - only used for eases that are optimized to make use of the internal code in the render() loop (ones that are activated with FastEase.activate()) **/ | ||
| 364 | protected var _easePower:uint; | ||
| 365 | /** @private 0 = standard function, 1 = optimized easeIn, 2 = optimized easeOut, 3 = optimized easeInOut. Only used for eases that are optimized to make use of the internal code in the render() loop (ones that are activated with FastEase.activate()) **/ | ||
| 366 | protected var _easeType:uint; | ||
| 367 | |||
| 368 | |||
| 369 | /** | ||
| 370 | * Works in conjunction with the repeat property, determining the behavior of each cycle; when yoyo is true, | ||
| 371 | * the tween will go back and forth, appearing to reverse every other cycle (this has no affect on the "reversed" | ||
| 372 | * property though). So if repeat is 2 and yoyo is false, it will look like: start - 1 - 2 - 3 - 1 - 2 - 3 - 1 - 2 - 3 - end. | ||
| 373 | * But if repeat is 2 and yoyo is true, it will look like: start - 1 - 2 - 3 - 3 - 2 - 1 - 1 - 2 - 3 - end. | ||
| 374 | **/ | ||
| 375 | public var yoyo:Boolean; | ||
| 376 | |||
| 377 | /** | ||
| 378 | * Constructor | ||
| 379 | * | ||
| 380 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 381 | * @param duration Duration in seconds (or in frames if the tween's timing mode is frames-based) | ||
| 382 | * @param vars An object containing the end values of the properties you're tweening. For example, to tween to x=100, y=100, you could pass {x:100, y:100}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 383 | */ | ||
| 384 | public function TweenMax(target:Object, duration:Number, vars:Object) { | ||
| 385 | super(target, duration, vars); | ||
| 386 | if (TweenLite.version < 11.2) { | ||
| 387 | throw new Error("TweenMax error! Please update your TweenLite class or try deleting your ASO files. TweenMax requires a more recent version. Download updates at http://www.TweenMax.com."); | ||
| 388 | } | ||
| 389 | this.yoyo = Boolean(this.vars.yoyo); | ||
| 390 | _repeat = (this.vars.repeat) ? int(this.vars.repeat) : 0; | ||
| 391 | _repeatDelay = (this.vars.repeatDelay) ? Number(this.vars.repeatDelay) : 0; | ||
| 392 | this.cacheIsDirty = true; //ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it. | ||
| 393 | |||
| 394 | if (this.vars.onCompleteListener || this.vars.onInitListener || this.vars.onUpdateListener || this.vars.onStartListener || this.vars.onRepeatListener || this.vars.onReverseCompleteListener) { | ||
| 395 | initDispatcher(); | ||
| 396 | if (duration == 0 && _delay == 0) { | ||
| 397 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.UPDATE)); | ||
| 398 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.COMPLETE)); | ||
| 399 | } | ||
| 400 | } | ||
| 401 | if (this.vars.timeScale && !(this.target is TweenCore)) { | ||
| 402 | this.cachedTimeScale = this.vars.timeScale; | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | /** | ||
| 407 | * @private | ||
| 408 | * Initializes the property tweens, determining their start values and amount of change. | ||
| 409 | * Also triggers overwriting if necessary and sets the _hasUpdate variable. | ||
| 410 | */ | ||
| 411 | override protected function init():void { | ||
| 412 | if (this.vars.startAt) { | ||
| 413 | this.vars.startAt.overwrite = 0; | ||
| 414 | this.vars.startAt.immediateRender = true; | ||
| 415 | var startTween:TweenMax = new TweenMax(this.target, 0, this.vars.startAt); | ||
| 416 | } | ||
| 417 | if (_dispatcher) { | ||
| 418 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.INIT)); | ||
| 419 | } | ||
| 420 | super.init(); | ||
| 421 | if (_ease in fastEaseLookup) { | ||
| 422 | _easeType = fastEaseLookup[_ease][0]; | ||
| 423 | _easePower = fastEaseLookup[_ease][1]; | ||
| 424 | } | ||
| 425 | //accommodate rounding if necessary... | ||
| 426 | if (this.vars.roundProps != null && "roundProps" in TweenLite.plugins) { | ||
| 427 | var j:int, prop:String, multiProps:String, rp:Array = this.vars.roundProps, plugin:Object, ptPlugin:PropTween, pt:PropTween; | ||
| 428 | var i:int = rp.length; | ||
| 429 | while (--i > -1) { | ||
| 430 | prop = rp[i]; | ||
| 431 | pt = this.cachedPT1; | ||
| 432 | while (pt) { | ||
| 433 | if (pt.name == prop) { | ||
| 434 | if (pt.isPlugin) { | ||
| 435 | pt.target.round = true; | ||
| 436 | } else { | ||
| 437 | if (plugin == null) { | ||
| 438 | plugin = new TweenLite.plugins.roundProps(); | ||
| 439 | plugin.add(pt.target, prop, pt.start, pt.change); | ||
| 440 | _hasPlugins = true; | ||
| 441 | this.cachedPT1 = ptPlugin = insertPropTween(plugin, "changeFactor", 0, 1, "_MULTIPLE_", true, this.cachedPT1); | ||
| 442 | } else { | ||
| 443 | plugin.add(pt.target, prop, pt.start, pt.change); //using a single plugin for rounding speeds processing | ||
| 444 | } | ||
| 445 | this.removePropTween(pt); | ||
| 446 | this.propTweenLookup[prop] = ptPlugin; | ||
| 447 | } | ||
| 448 | } else if (pt.isPlugin && pt.name == "_MULTIPLE_" && !pt.target.round) { | ||
| 449 | multiProps = " " + pt.target.overwriteProps.join(" ") + " "; | ||
| 450 | if (multiProps.indexOf(" " + prop + " ") != -1) { | ||
| 451 | pt.target.round = true; | ||
| 452 | } | ||
| 453 | } | ||
| 454 | pt = pt.nextNode; | ||
| 455 | } | ||
| 456 | } | ||
| 457 | } | ||
| 458 | } | ||
| 459 | |||
| 460 | /** | ||
| 461 | * @private | ||
| 462 | * Inserts a new property tween into the linked list. | ||
| 463 | * | ||
| 464 | * @param target Object whose property is being tweened | ||
| 465 | * @param property Name of the property that is being tweened (according to the property tween's target) | ||
| 466 | * @param start Starting value of the property | ||
| 467 | * @param end End value of the property (if it is a String, it will be interpreted as relative) | ||
| 468 | * @param name The name of the property that is being tweened (according to tween's target). This can be different than the "property". For example, for a bezier tween, the target could be the plugin, the property could be "changeFactor", and the name could be "x" or "_MULTIPLE_" if the plugin is managing more than one property. This aids in overwrite management. | ||
| 469 | * @param isPlugin Indicates whether or not the property tween is a plugin | ||
| 470 | * @param nextNode Next PropTween instance in the linked list. (this just helps speed things up) | ||
| 471 | * @return PropTween instance that was created/inserted | ||
| 472 | */ | ||
| 473 | protected function insertPropTween(target:Object, property:String, start:Number, end:*, name:String, isPlugin:Boolean, nextNode:PropTween):PropTween { | ||
| 474 | var pt:PropTween = new PropTween(target, property, start, (typeof(end) == "number") ? end - start : Number(end), name, isPlugin, nextNode); | ||
| 475 | if (isPlugin && name == "_MULTIPLE_") { | ||
| 476 | var op:Array = target.overwriteProps; | ||
| 477 | var i:int = op.length; | ||
| 478 | while (--i > -1) { | ||
| 479 | this.propTweenLookup[op[i]] = pt; | ||
| 480 | } | ||
| 481 | } else { | ||
| 482 | this.propTweenLookup[name] = pt; | ||
| 483 | } | ||
| 484 | return pt; | ||
| 485 | } | ||
| 486 | |||
| 487 | /** | ||
| 488 | * @private | ||
| 489 | * Removes a PropTween from the linked list | ||
| 490 | * | ||
| 491 | * @param propTween PropTween to remove | ||
| 492 | * @return Boolean value indicating whether or not properties may have changed on the target when the PropTween was disabled. For example, when a motionBlur (plugin) is disabled, it swaps out a BitmapData for the target and may alter the alpha. We need to know this in order to determine whether or not a new tween that is overwriting this one should be re-initted() with the changed properties. | ||
| 493 | */ | ||
| 494 | protected function removePropTween(propTween:PropTween):Boolean { | ||
| 495 | if (propTween.nextNode) { | ||
| 496 | propTween.nextNode.prevNode = propTween.prevNode; | ||
| 497 | } | ||
| 498 | if (propTween.prevNode) { | ||
| 499 | propTween.prevNode.nextNode = propTween.nextNode; | ||
| 500 | } else if (this.cachedPT1 == propTween) { | ||
| 501 | this.cachedPT1 = propTween.nextNode; | ||
| 502 | } | ||
| 503 | if (propTween.isPlugin && propTween.target.onDisable) { | ||
| 504 | propTween.target.onDisable(); //some plugins need to be notified so they can perform cleanup tasks first | ||
| 505 | if (propTween.target.activeDisable) { | ||
| 506 | return true; | ||
| 507 | } | ||
| 508 | } | ||
| 509 | return false; | ||
| 510 | } | ||
| 511 | |||
| 512 | /** @inheritDoc **/ | ||
| 513 | override public function invalidate():void { | ||
| 514 | this.yoyo = Boolean(this.vars.yoyo == true); | ||
| 515 | _repeat = (this.vars.repeat) ? Number(this.vars.repeat) : 0; | ||
| 516 | _repeatDelay = (this.vars.repeatDelay) ? Number(this.vars.repeatDelay) : 0; | ||
| 517 | _hasUpdateListener = false; | ||
| 518 | if (this.vars.onCompleteListener != null || this.vars.onUpdateListener != null || this.vars.onStartListener != null) { | ||
| 519 | initDispatcher(); | ||
| 520 | } | ||
| 521 | setDirtyCache(true); | ||
| 522 | super.invalidate(); | ||
| 523 | } | ||
| 524 | |||
| 525 | /** | ||
| 526 | * Updates tweening values on the fly so that they appear to seamlessly change course even if the tween is in-progress. | ||
| 527 | * Think of it as dynamically updating the <code>vars</code> object that you passed in to the tween when it was originally | ||
| 528 | * created. You do <b>NOT</b> need to redefine all of the <code>vars</code> values - only the ones that you want | ||
| 529 | * to update. You can even define new properties that you didn't define in the original <code>vars</code> object. | ||
| 530 | * If the <code>resetDuration</code> parameter is <code>true</code> and the tween has already started (or finished), | ||
| 531 | * <code>updateTo()</code> will restart the tween. Otherwise, the tween's timing will be honored. And if | ||
| 532 | * <code>resetDuration</code> is <code>false</code> and the tween is in-progress, the starting values of each | ||
| 533 | * property will be adjusted so that the tween appears to seamlessly redirect to the new destination values. | ||
| 534 | * For example:<br /><br /><code> | ||
| 535 | * | ||
| 536 | * //create the tween <br /> | ||
| 537 | * var tween:TweenMax = new TweenMax(mc, 2, {x:100, y:200, alpha:0.5});<br /><br /> | ||
| 538 | * | ||
| 539 | * //then later, update the destination x and y values, restarting the tween<br /> | ||
| 540 | * tween.updateTo({x:300, y:0}, true);<br /><br /> | ||
| 541 | * | ||
| 542 | * //or to update the values mid-tween while keeping the end time the same (don't restart the tween), do this:<br /> | ||
| 543 | * tween.updateTo({x:300, y:0}, false);<br /><br /></code> | ||
| 544 | * | ||
| 545 | * Note: If you plan to constantly update values, please look into using the <code>DynamicPropsPlugin</code>. | ||
| 546 | * | ||
| 547 | * @param vars Object containing properties with the end values that should be udpated. You do <b>NOT</b> need to redefine all of the original <code>vars</code> values - only the ones that should be updated (although if you change a plugin value, you will need to fully define it). For example, to update the destination <code>x</code> value to 300 and the destination <code>y</code> value to 500, pass: <code>{x:300, y:500}</code>. | ||
| 548 | * @param resetDuration If the tween has already started (or finished) and <code>resetDuration</code> is true, the tween will restart. If <code>resetDuration</code> is false, the tween's timing will be honored (no restart) and each tweening property's starting value will be adjusted so that it appears to seamlessly redirect to the new destination value. | ||
| 549 | **/ | ||
| 550 | public function updateTo(vars:Object, resetDuration:Boolean=false):void { | ||
| 551 | var curRatio:Number = this.ratio; | ||
| 552 | if (resetDuration && this.timeline != null && this.cachedStartTime < this.timeline.cachedTime) { | ||
| 553 | this.cachedStartTime = this.timeline.cachedTime; | ||
| 554 | this.setDirtyCache(false); | ||
| 555 | if (this.gc) { | ||
| 556 | this.setEnabled(true, false); | ||
| 557 | } else { | ||
| 558 | this.timeline.addChild(this); //ensures that any necessary re-sequencing of TweenCores in the timeline occurs to make sure the rendering order is correct. | ||
| 559 | } | ||
| 560 | } | ||
| 561 | for (var p:String in vars) { | ||
| 562 | this.vars[p] = vars[p]; | ||
| 563 | } | ||
| 564 | if (this.initted) { | ||
| 565 | this.initted = false; | ||
| 566 | if (!resetDuration) { | ||
| 567 | init(); | ||
| 568 | if (!resetDuration && this.cachedTime > 0 && this.cachedTime < this.cachedDuration) { | ||
| 569 | var inv:Number = 1 / (1 - curRatio); | ||
| 570 | var pt:PropTween = this.cachedPT1, endValue:Number; | ||
| 571 | while (pt) { | ||
| 572 | endValue = pt.start + pt.change; | ||
| 573 | pt.change *= inv; | ||
| 574 | pt.start = endValue - pt.change; | ||
| 575 | pt = pt.nextNode; | ||
| 576 | } | ||
| 577 | } | ||
| 578 | } | ||
| 579 | } | ||
| 580 | } | ||
| 581 | |||
| 582 | /** | ||
| 583 | * Adjusts a destination value on the fly, optionally adjusting the start values so that it appears to redirect seamlessly | ||
| 584 | * without skipping/jerking (<b>this method has been deprecated in favor of <code>updateTo()</code></b>). | ||
| 585 | * If you plan to constantly update values, please look into using the DynamicPropsPlugin. | ||
| 586 | * | ||
| 587 | * @param property Name of the property that should be updated. For example, "x". | ||
| 588 | * @param value The new destination value | ||
| 589 | * @param adjustStartValues If true, the property's start value will be adjusted to make the tween appear to seamlessly/smoothly redirect without any skipping/jerking. Beware that if start values are adjusted, reversing the tween will not make it travel back to the original starting value. | ||
| 590 | **/ | ||
| 591 | public function setDestination(property:String, value:*, adjustStartValues:Boolean=true):void { | ||
| 592 | var vars:Object = {}; | ||
| 593 | vars[property] = value; | ||
| 594 | updateTo(vars, !adjustStartValues); | ||
| 595 | } | ||
| 596 | |||
| 597 | |||
| 598 | /** | ||
| 599 | * Allows particular properties of the tween to be killed, much like the killVars() method | ||
| 600 | * except that killProperties() accepts an Array of property names. | ||
| 601 | * | ||
| 602 | * @param names An Array of property names whose tweens should be killed immediately. | ||
| 603 | */ | ||
| 604 | public function killProperties(names:Array):void { | ||
| 605 | var v:Object = {}, i:int = names.length; | ||
| 606 | while (--i > -1) { | ||
| 607 | v[names[i]] = true; | ||
| 608 | } | ||
| 609 | killVars(v); | ||
| 610 | } | ||
| 611 | |||
| 612 | /** | ||
| 613 | * @private | ||
| 614 | * Renders the tween at a particular time (or frame number for frames-based tweens). | ||
| 615 | * The time is based simply on the overall duration. For example, if a tween's duration | ||
| 616 | * is 3, <code>renderTime(1.5)</code> would render it at the halfway finished point. | ||
| 617 | * | ||
| 618 | * @param time time (or frame number for frames-based tweens) to render. | ||
| 619 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 620 | * @param force Normally the tween will skip rendering if the time matches the cachedTotalTime (to improve performance), but if force is true, it forces a render. This is primarily used internally for tweens with durations of zero in TimelineLite/Max instances. | ||
| 621 | */ | ||
| 622 | override public function renderTime(time:Number, suppressEvents:Boolean=false, force:Boolean=false):void { | ||
| 623 | var totalDur:Number = (this.cacheIsDirty) ? this.totalDuration : this.cachedTotalDuration, prevTime:Number = this.cachedTime, isComplete:Boolean, repeated:Boolean, setRatio:Boolean; | ||
| 624 | if (time >= totalDur) { | ||
| 625 | this.cachedTotalTime = totalDur; | ||
| 626 | this.cachedTime = this.cachedDuration; | ||
| 627 | this.ratio = 1; | ||
| 628 | isComplete = true; | ||
| 629 | if (this.cachedDuration == 0) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. | ||
| 630 | if ((time == 0 || _rawPrevTime < 0) && _rawPrevTime != time) { | ||
| 631 | force = true; | ||
| 632 | } | ||
| 633 | _rawPrevTime = time; | ||
| 634 | } | ||
| 635 | |||
| 636 | } else if (time <= 0) { | ||
| 637 | if (time < 0) { | ||
| 638 | this.active = false; | ||
| 639 | if (this.cachedDuration == 0) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. | ||
| 640 | if (_rawPrevTime > 0) { | ||
| 641 | force = true; | ||
| 642 | isComplete = true; | ||
| 643 | } | ||
| 644 | _rawPrevTime = time; | ||
| 645 | } | ||
| 646 | } | ||
| 647 | this.cachedTotalTime = this.cachedTime = this.ratio = 0; | ||
| 648 | if (this.cachedReversed && prevTime != 0) { | ||
| 649 | isComplete = true; | ||
| 650 | } | ||
| 651 | } else { | ||
| 652 | this.cachedTotalTime = this.cachedTime = time; | ||
| 653 | setRatio = true; | ||
| 654 | } | ||
| 655 | |||
| 656 | if (_repeat != 0) { | ||
| 657 | |||
| 658 | var cycleDuration:Number = this.cachedDuration + _repeatDelay; | ||
| 659 | if (isComplete) { | ||
| 660 | if (this.yoyo && _repeat % 2) { | ||
| 661 | this.cachedTime = this.ratio = 0; | ||
| 662 | } | ||
| 663 | } else if (time > 0) { | ||
| 664 | var prevCycles:int = _cyclesComplete; | ||
| 665 | _cyclesComplete = int(this.cachedTotalTime / cycleDuration); | ||
| 666 | if (_cyclesComplete == this.cachedTotalTime / cycleDuration) { | ||
| 667 | _cyclesComplete--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning) | ||
| 668 | } | ||
| 669 | if (prevCycles != _cyclesComplete) { | ||
| 670 | repeated = true; | ||
| 671 | } | ||
| 672 | |||
| 673 | this.cachedTime = ((this.cachedTotalTime / cycleDuration) - _cyclesComplete) * cycleDuration; //originally this.cachedTotalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but Flash reports it as 0.79999999!) | ||
| 674 | |||
| 675 | if (this.yoyo && _cyclesComplete % 2) { | ||
| 676 | this.cachedTime = this.cachedDuration - this.cachedTime; | ||
| 677 | } else if (this.cachedTime >= this.cachedDuration) { | ||
| 678 | this.cachedTime = this.cachedDuration; | ||
| 679 | this.ratio = 1; | ||
| 680 | setRatio = false; | ||
| 681 | } | ||
| 682 | |||
| 683 | if (this.cachedTime <= 0) { | ||
| 684 | this.cachedTime = this.ratio = 0; | ||
| 685 | setRatio = false; | ||
| 686 | } | ||
| 687 | } | ||
| 688 | |||
| 689 | } | ||
| 690 | |||
| 691 | if (prevTime == this.cachedTime && !force) { | ||
| 692 | return; | ||
| 693 | } else if (!this.initted) { | ||
| 694 | init(); | ||
| 695 | } | ||
| 696 | if (!this.active && !this.cachedPaused) { | ||
| 697 | this.active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. | ||
| 698 | } | ||
| 699 | |||
| 700 | if (setRatio) { | ||
| 701 | //if the ease is optimized, process it inline (function calls are expensive performance-wise)... | ||
| 702 | if (_easeType) { | ||
| 703 | var power:int = _easePower; | ||
| 704 | var val:Number = this.cachedTime / this.cachedDuration; | ||
| 705 | if (_easeType == 2) { //easeOut | ||
| 706 | this.ratio = val = 1 - val; | ||
| 707 | while (--power > -1) { | ||
| 708 | this.ratio = val * this.ratio; | ||
| 709 | } | ||
| 710 | this.ratio = 1 - this.ratio; | ||
| 711 | } else if (_easeType == 1) { //easeIn | ||
| 712 | this.ratio = val; | ||
| 713 | while (--power > -1) { | ||
| 714 | this.ratio = val * this.ratio; | ||
| 715 | } | ||
| 716 | } else { //easeInOut | ||
| 717 | if (val < 0.5) { | ||
| 718 | this.ratio = val = val * 2; | ||
| 719 | while (--power > -1) { | ||
| 720 | this.ratio = val * this.ratio; | ||
| 721 | } | ||
| 722 | this.ratio = this.ratio * 0.5; | ||
| 723 | } else { | ||
| 724 | this.ratio = val = (1 - val) * 2; | ||
| 725 | while (--power > -1) { | ||
| 726 | this.ratio = val * this.ratio; | ||
| 727 | } | ||
| 728 | this.ratio = 1 - (0.5 * this.ratio); | ||
| 729 | } | ||
| 730 | } | ||
| 731 | |||
| 732 | } else { | ||
| 733 | this.ratio = _ease(this.cachedTime, 0, 1, this.cachedDuration); | ||
| 734 | } | ||
| 735 | } | ||
| 736 | |||
| 737 | if (prevTime == 0 && this.cachedTotalTime != 0 && !suppressEvents) { | ||
| 738 | if (this.vars.onStart) { | ||
| 739 | this.vars.onStart.apply(null, this.vars.onStartParams); | ||
| 740 | } | ||
| 741 | if (_dispatcher) { | ||
| 742 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.START)); | ||
| 743 | } | ||
| 744 | } | ||
| 745 | |||
| 746 | var pt:PropTween = this.cachedPT1; | ||
| 747 | while (pt) { | ||
| 748 | pt.target[pt.property] = pt.start + (this.ratio * pt.change); | ||
| 749 | pt = pt.nextNode; | ||
| 750 | } | ||
| 751 | if (_hasUpdate && !suppressEvents) { | ||
| 752 | this.vars.onUpdate.apply(null, this.vars.onUpdateParams); | ||
| 753 | } | ||
| 754 | if (_hasUpdateListener && !suppressEvents) { | ||
| 755 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.UPDATE)); | ||
| 756 | } | ||
| 757 | if (isComplete) { | ||
| 758 | if (_hasPlugins && this.cachedPT1) { | ||
| 759 | onPluginEvent("onComplete", this); | ||
| 760 | } | ||
| 761 | complete(true, suppressEvents); | ||
| 762 | } else if (repeated && !suppressEvents) { | ||
| 763 | if (this.vars.onRepeat) { | ||
| 764 | this.vars.onRepeat.apply(null, this.vars.onRepeatParams); | ||
| 765 | } | ||
| 766 | if (_dispatcher) { | ||
| 767 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.REPEAT)); | ||
| 768 | } | ||
| 769 | } | ||
| 770 | } | ||
| 771 | |||
| 772 | /** | ||
| 773 | * Forces the tween to completion. | ||
| 774 | * | ||
| 775 | * @param skipRender to skip rendering the final state of the tween, set skipRender to true. | ||
| 776 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 777 | */ | ||
| 778 | override public function complete(skipRender:Boolean=false, suppressEvents:Boolean=false):void { | ||
| 779 | super.complete(skipRender, suppressEvents); | ||
| 780 | if (!suppressEvents && _dispatcher) { | ||
| 781 | if (this.cachedTotalTime == this.cachedTotalDuration && !this.cachedReversed) { | ||
| 782 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.COMPLETE)); | ||
| 783 | } else if (this.cachedReversed && this.cachedTotalTime == 0) { | ||
| 784 | _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.REVERSE_COMPLETE)); | ||
| 785 | } | ||
| 786 | } | ||
| 787 | } | ||
| 788 | |||
| 789 | |||
| 790 | //---- EVENT DISPATCHING ---------------------------------------------------------------------------------------------------------- | ||
| 791 | |||
| 792 | /** | ||
| 793 | * @private | ||
| 794 | * Initializes Event dispatching functionality | ||
| 795 | */ | ||
| 796 | protected function initDispatcher():void { | ||
| 797 | if (_dispatcher == null) { | ||
| 798 | _dispatcher = new EventDispatcher(this); | ||
| 799 | } | ||
| 800 | if (this.vars.onInitListener is Function) { | ||
| 801 | _dispatcher.addEventListener(TweenEvent.INIT, this.vars.onInitListener, false, 0, true); | ||
| 802 | } | ||
| 803 | if (this.vars.onStartListener is Function) { | ||
| 804 | _dispatcher.addEventListener(TweenEvent.START, this.vars.onStartListener, false, 0, true); | ||
| 805 | } | ||
| 806 | if (this.vars.onUpdateListener is Function) { | ||
| 807 | _dispatcher.addEventListener(TweenEvent.UPDATE, this.vars.onUpdateListener, false, 0, true); | ||
| 808 | _hasUpdateListener = true; | ||
| 809 | } | ||
| 810 | if (this.vars.onCompleteListener is Function) { | ||
| 811 | _dispatcher.addEventListener(TweenEvent.COMPLETE, this.vars.onCompleteListener, false, 0, true); | ||
| 812 | } | ||
| 813 | if (this.vars.onRepeatListener is Function) { | ||
| 814 | _dispatcher.addEventListener(TweenEvent.REPEAT, this.vars.onRepeatListener, false, 0, true); | ||
| 815 | } | ||
| 816 | if (this.vars.onReverseCompleteListener is Function) { | ||
| 817 | _dispatcher.addEventListener(TweenEvent.REVERSE_COMPLETE, this.vars.onReverseCompleteListener, false, 0, true); | ||
| 818 | } | ||
| 819 | } | ||
| 820 | /** @private **/ | ||
| 821 | public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void { | ||
| 822 | if (_dispatcher == null) { | ||
| 823 | initDispatcher(); | ||
| 824 | } | ||
| 825 | if (type == TweenEvent.UPDATE) { | ||
| 826 | _hasUpdateListener = true; | ||
| 827 | } | ||
| 828 | _dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference); | ||
| 829 | } | ||
| 830 | /** @private **/ | ||
| 831 | public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void { | ||
| 832 | if (_dispatcher) { | ||
| 833 | _dispatcher.removeEventListener(type, listener, useCapture); | ||
| 834 | } | ||
| 835 | } | ||
| 836 | /** @private **/ | ||
| 837 | public function hasEventListener(type:String):Boolean { | ||
| 838 | return (_dispatcher == null) ? false : _dispatcher.hasEventListener(type); | ||
| 839 | } | ||
| 840 | /** @private **/ | ||
| 841 | public function willTrigger(type:String):Boolean { | ||
| 842 | return (_dispatcher == null) ? false : _dispatcher.willTrigger(type); | ||
| 843 | } | ||
| 844 | /** @private **/ | ||
| 845 | public function dispatchEvent(e:Event):Boolean { | ||
| 846 | return (_dispatcher == null) ? false : _dispatcher.dispatchEvent(e); | ||
| 847 | } | ||
| 848 | |||
| 849 | |||
| 850 | //---- STATIC FUNCTIONS ----------------------------------------------------------------------------------------------------------- | ||
| 851 | |||
| 852 | /** | ||
| 853 | * Static method for creating a TweenMax instance. This can be more intuitive for some developers | ||
| 854 | * and shields them from potential garbage collection issues that could arise when assigning a | ||
| 855 | * tween instance to a variable that persists. The following lines of code produce exactly | ||
| 856 | * the same result: <br /><br /><code> | ||
| 857 | * | ||
| 858 | * var myTween:TweenMax = new TweenMax(mc, 1, {x:100}); <br /> | ||
| 859 | * TweenMax.to(mc, 1, {x:100}); <br /> | ||
| 860 | * var myTween:TweenMax = TweenMax.to(mc, 1, {x:100}); <br /><br /></code> | ||
| 861 | * | ||
| 862 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 863 | * @param duration Duration in seconds (or in frames for frames-based tweens) | ||
| 864 | * @param vars An object containing the end values of the properties you're tweening. For example, to tween to x=100, y=100, you could pass {x:100, y:100}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 865 | * @return TweenMax instance | ||
| 866 | */ | ||
| 867 | public static function to(target:Object, duration:Number, vars:Object):TweenMax { | ||
| 868 | return new TweenMax(target, duration, vars); | ||
| 869 | } | ||
| 870 | |||
| 871 | /** | ||
| 872 | * Static method for creating a TweenMax instance that tweens in the opposite direction | ||
| 873 | * compared to a <code>TweenMax.to()</code> tween. In other words, you define the START values in the | ||
| 874 | * vars object instead of the end values, and the tween will use the current values as | ||
| 875 | * the end values. This can be very useful for animating things into place on the stage | ||
| 876 | * because you can build them in their end positions and do some simple <code>TweenMax.from()</code> | ||
| 877 | * calls to animate them into place. <b>NOTE:</b> By default, <code>immediateRender</code> | ||
| 878 | * is <code>true</code> for from() tweens, meaning that they immediately render their starting state | ||
| 879 | * regardless of any delay that is specified. You can override this behavior by passing | ||
| 880 | * <code>immediateRender:false</code> in the <code>vars</code> object so that it will wait to | ||
| 881 | * render until the tween actually begins (often the desired behavior when inserting into timelines). | ||
| 882 | * To illustrate the default behavior, the following code will immediately set the <code>alpha</code> of <code>mc</code> | ||
| 883 | * to 0 and then wait 2 seconds before tweening the <code>alpha</code> back to 1 over the course | ||
| 884 | * of 1.5 seconds:<br /><br /><code> | ||
| 885 | * | ||
| 886 | * TweenMax.from(mc, 1.5, {alpha:0, delay:2});</code> | ||
| 887 | * | ||
| 888 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 889 | * @param duration Duration in seconds (or in frames for frames-based tweens) | ||
| 890 | * @param vars An object containing the start values of the properties you're tweening. For example, to tween from x=100, y=100, you could pass {x:100, y:100}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 891 | * @return TweenMax instance | ||
| 892 | */ | ||
| 893 | public static function from(target:Object, duration:Number, vars:Object):TweenMax { | ||
| 894 | vars.runBackwards = true; | ||
| 895 | if (!("immediateRender" in vars)) { | ||
| 896 | vars.immediateRender = true; | ||
| 897 | } | ||
| 898 | return new TweenMax(target, duration, vars); | ||
| 899 | } | ||
| 900 | |||
| 901 | /** | ||
| 902 | * Static method for creating a TweenMax instance that tweens from a particular set of | ||
| 903 | * values to another set of values, as opposed to a normal to() or from() tween which are | ||
| 904 | * based on the target's current values. <b>NOTE</b>: Only put starting values | ||
| 905 | * in the fromVars parameter - all special properties for the tween (like onComplete, onUpdate, delay, etc.) belong | ||
| 906 | * in the toVars parameter. | ||
| 907 | * | ||
| 908 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 909 | * @param duration Duration in seconds (or in frames for frames-based tweens) | ||
| 910 | * @param fromVars An object containing the starting values of the properties you're tweening. For example, to tween from x=0, y=0, you could pass {x:0, y:0}. Only put starting values in the fromVars parameter - all special properties for the tween (like onComplete, onUpdate, delay, etc.) belong in the toVars parameter. | ||
| 911 | * @param toVars An object containing the ending values of the properties you're tweening. For example, to tween to x=100, y=100, you could pass {x:100, y:100}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 912 | * @return TweenMax instance | ||
| 913 | */ | ||
| 914 | public static function fromTo(target:Object, duration:Number, fromVars:Object, toVars:Object):TweenMax { | ||
| 915 | toVars.startAt = fromVars; | ||
| 916 | if (fromVars.immediateRender) { | ||
| 917 | toVars.immediateRender = true; | ||
| 918 | } | ||
| 919 | return new TweenMax(target, duration, toVars); | ||
| 920 | } | ||
| 921 | |||
| 922 | /** | ||
| 923 | * Tween multiple objects to the same end values. The "stagger" parameter | ||
| 924 | * staggers the start time of each tween. For example, you might want to have 5 MovieClips move down | ||
| 925 | * 100 pixels while fading out, and stagger the start times slightly by 0.2 seconds: <br /><br /><code> | ||
| 926 | * | ||
| 927 | * TweenMax.allTo([mc1, mc2, mc3, mc4, mc5], 1, {y:"100", alpha:0}, 0.2); <br /><br /></code> | ||
| 928 | * | ||
| 929 | * Note: You can easily add a group of tweens to a TimelineLite/Max instance using allTo() in conjunction with the | ||
| 930 | * insertMultipe() method of a timeline, like:<br /><br /> | ||
| 931 | * <code>myTimeline.insertMultiple(TweenMax.allTo([mc1, mc2, mc3], 1, {alpha:0, y:"100"}, 0.1));</code> | ||
| 932 | * | ||
| 933 | * @param targets An Array of objects to tween. | ||
| 934 | * @param duration Duration in seconds (or frames for frames-based tweens) of the tween | ||
| 935 | * @param vars An object containing the end values of all the properties you'd like to have tweened (or if you're using the TweenMax.allFrom() method, these variables would define the BEGINNING values). | ||
| 936 | * @param stagger Staggers the start time of each tween. For example, you might want to have 5 MovieClips move down 100 pixels while fading out, and stagger the start times slightly by 0.2 seconds, you could do: <code>TweenMax.allTo([mc1, mc2, mc3, mc4, mc5], 1, {y:"100", alpha:0}, 0.2)</code>. | ||
| 937 | * @param onCompleteAll A function to call when all of the tweens have completed. | ||
| 938 | * @param onCompleteAllParams An Array of parameters to pass the onCompleteAll function when all the tweens have completed. | ||
| 939 | * @return Array of TweenMax tweens | ||
| 940 | */ | ||
| 941 | public static function allTo(targets:Array, duration:Number, vars:Object, stagger:Number=0, onCompleteAll:Function=null, onCompleteAllParams:Array=null):Array { | ||
| 942 | var i:int, varsDup:Object, p:String; | ||
| 943 | var l:uint = targets.length; | ||
| 944 | var a:Array = []; | ||
| 945 | var curDelay:Number = ("delay" in vars) ? Number(vars.delay) : 0; | ||
| 946 | var onCompleteProxy:Function = vars.onComplete; | ||
| 947 | var onCompleteParamsProxy:Array = vars.onCompleteParams; | ||
| 948 | var lastIndex:int = (stagger <= 0) ? 0 : l - 1; | ||
| 949 | for (i = 0; i < l; i++) { | ||
| 950 | varsDup = {}; | ||
| 951 | for (p in vars) { | ||
| 952 | varsDup[p] = vars[p]; | ||
| 953 | } | ||
| 954 | varsDup.delay = curDelay; | ||
| 955 | if (i == lastIndex && onCompleteAll != null) { | ||
| 956 | varsDup.onComplete = function():void { | ||
| 957 | if (onCompleteProxy != null) { | ||
| 958 | onCompleteProxy.apply(null, onCompleteParamsProxy); | ||
| 959 | } | ||
| 960 | onCompleteAll.apply(null, onCompleteAllParams); | ||
| 961 | } | ||
| 962 | } | ||
| 963 | a[a.length] = new TweenMax(targets[i], duration, varsDup); | ||
| 964 | curDelay += stagger; | ||
| 965 | } | ||
| 966 | return a; | ||
| 967 | } | ||
| 968 | |||
| 969 | /** | ||
| 970 | * Exactly the same as TweenMax.allTo(), but instead of tweening the properties from where they're | ||
| 971 | * at currently to whatever you define, this tweens them the opposite way - from where you define TO | ||
| 972 | * where ever they are when the tweens begin. This is useful when things are set up on the stage the way they should | ||
| 973 | * end up and you just want to tween them into place. <b>NOTE:</b> By default, <code>immediateRender</code> | ||
| 974 | * is <code>true</code> for allFrom() tweens, meaning that they immediately render their starting state | ||
| 975 | * regardless of any delay or stagger that is specified. You can override this behavior by passing | ||
| 976 | * <code>immediateRender:false</code> in the <code>vars</code> object so that each tween will wait to render until | ||
| 977 | * any delay/stagger has passed (often the desired behavior when inserting into timelines). To illustrate | ||
| 978 | * the default behavior, the following code will immediately set the <code>alpha</code> of <code>mc1</code>, | ||
| 979 | * <code>mc2</code>, and <code>mc3</code> to 0 and then wait 2 seconds before tweening each <code>alpha</code> | ||
| 980 | * back to 1 over the course of 1.5 seconds with 0.1 seconds lapsing between the start times of each:<br /><br /><code> | ||
| 981 | * | ||
| 982 | * TweenMax.allFrom([mc1, mc2, mc3], 1.5, {alpha:0, delay:2}, 0.1);</code> | ||
| 983 | * | ||
| 984 | * @param targets An Array of objects to tween. | ||
| 985 | * @param duration Duration (in seconds) of the tween (or in frames for frames-based tweens) | ||
| 986 | * @param vars An object containing the start values of all the properties you'd like to have tweened. | ||
| 987 | * @param stagger Staggers the start time of each tween. For example, you might want to have 5 MovieClips move down 100 pixels while fading from alpha:0, and stagger the start times slightly by 0.2 seconds, you could do: <code>TweenMax.allFromTo([mc1, mc2, mc3, mc4, mc5], 1, {y:"-100", alpha:0}, 0.2)</code>. | ||
| 988 | * @param onCompleteAll A function to call when all of the tweens have completed. | ||
| 989 | * @param onCompleteAllParams An Array of parameters to pass the onCompleteAll function when all the tweens have completed. | ||
| 990 | * @return Array of TweenMax instances | ||
| 991 | */ | ||
| 992 | public static function allFrom(targets:Array, duration:Number, vars:Object, stagger:Number=0, onCompleteAll:Function=null, onCompleteAllParams:Array=null):Array { | ||
| 993 | vars.runBackwards = true; | ||
| 994 | if (!("immediateRender" in vars)) { | ||
| 995 | vars.immediateRender = true; | ||
| 996 | } | ||
| 997 | return allTo(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams); | ||
| 998 | } | ||
| 999 | |||
| 1000 | /** | ||
| 1001 | * Tweens multiple targets from a common set of starting values to a common set of ending values; exactly the same | ||
| 1002 | * as TweenMax.allTo(), but adds the ability to define the starting values. <b>NOTE</b>: Only put starting values | ||
| 1003 | * in the fromVars parameter - all special properties for the tween (like onComplete, onUpdate, delay, etc.) belong | ||
| 1004 | * in the toVars parameter. | ||
| 1005 | * | ||
| 1006 | * @param targets An Array of objects to tween. | ||
| 1007 | * @param duration Duration (in seconds) of the tween (or in frames for frames-based tweens) | ||
| 1008 | * @param fromVars An object containing the starting values of all the properties you'd like to have tweened. | ||
| 1009 | * @param toVars An object containing the ending values of all the properties you'd like to have tweened. | ||
| 1010 | * @param stagger Staggers the start time of each tween. For example, you might want to have 5 MovieClips move down from y:0 to y:100 while fading from alpha:0 to alpha:1, and stagger the start times slightly by 0.2 seconds, you could do: <code>TweenMax.allFromTo([mc1, mc2, mc3, mc4, mc5], 1, {y:0, alpha:0}, {y:100, alpha:1}, 0.2)</code>. | ||
| 1011 | * @param onCompleteAll A function to call when all of the tweens have completed. | ||
| 1012 | * @param onCompleteAllParams An Array of parameters to pass the onCompleteAll function when all the tweens have completed. | ||
| 1013 | * @return Array of TweenMax instances | ||
| 1014 | */ | ||
| 1015 | public static function allFromTo(targets:Array, duration:Number, fromVars:Object, toVars:Object, stagger:Number=0, onCompleteAll:Function=null, onCompleteAllParams:Array=null):Array { | ||
| 1016 | toVars.startAt = fromVars; | ||
| 1017 | if (fromVars.immediateRender) { | ||
| 1018 | toVars.immediateRender = true; | ||
| 1019 | } | ||
| 1020 | return allTo(targets, duration, toVars, stagger, onCompleteAll, onCompleteAllParams); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | /** | ||
| 1024 | * Provides a simple way to call a function after a set amount of time (or frames). You can | ||
| 1025 | * optionally pass any number of parameters to the function too. For example: <br /><br /><code> | ||
| 1026 | * | ||
| 1027 | * TweenMax.delayedCall(1, myFunction, ["param1", 2]);<br /> | ||
| 1028 | * function myFunction(param1:String, param2:Number):void {<br /> | ||
| 1029 | * trace("called myFunction and passed params: " + param1 + ", " + param2);<br /> | ||
| 1030 | * }<br /><br /></code> | ||
| 1031 | * | ||
| 1032 | * @param delay Delay in seconds (or frames if useFrames is true) before the function should be called | ||
| 1033 | * @param onComplete Function to call | ||
| 1034 | * @param onCompleteParams An Array of parameters to pass the function. | ||
| 1035 | * @return TweenMax instance | ||
| 1036 | */ | ||
| 1037 | public static function delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array=null, useFrames:Boolean=false):TweenMax { | ||
| 1038 | return new TweenMax(onComplete, 0, {delay:delay, onComplete:onComplete, onCompleteParams:onCompleteParams, immediateRender:false, useFrames:useFrames, overwrite:0}); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | /** | ||
| 1042 | * Gets all the tweens of a particular object. | ||
| 1043 | * | ||
| 1044 | * @param target The target object whose tweens you want returned | ||
| 1045 | * @return Array of tweens (could be TweenLite and/or TweenMax instances) | ||
| 1046 | */ | ||
| 1047 | public static function getTweensOf(target:Object):Array { | ||
| 1048 | var a:Array = masterList[target]; | ||
| 1049 | var toReturn:Array = []; | ||
| 1050 | if (a) { | ||
| 1051 | var i:int = a.length; | ||
| 1052 | var cnt:uint = 0; | ||
| 1053 | while (--i > -1) { | ||
| 1054 | if (!a[i].gc) { | ||
| 1055 | toReturn[cnt++] = a[i]; | ||
| 1056 | } | ||
| 1057 | } | ||
| 1058 | } | ||
| 1059 | return toReturn; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | /** | ||
| 1063 | * Determines whether or not a particular object is actively tweening. If a tween | ||
| 1064 | * is paused or hasn't started yet, it doesn't count as active. | ||
| 1065 | * | ||
| 1066 | * @param target Target object whose tweens you're checking | ||
| 1067 | * @return Boolean value indicating whether or not any active tweens were found | ||
| 1068 | */ | ||
| 1069 | public static function isTweening(target:Object):Boolean { | ||
| 1070 | var a:Array = getTweensOf(target); | ||
| 1071 | var i:int = a.length; | ||
| 1072 | var tween:TweenLite; | ||
| 1073 | while (--i > -1) { | ||
| 1074 | tween = a[i]; | ||
| 1075 | if ((tween.active || (tween.cachedStartTime == tween.timeline.cachedTime && tween.timeline.active))) { | ||
| 1076 | return true; | ||
| 1077 | } | ||
| 1078 | } | ||
| 1079 | return false; | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | /** | ||
| 1083 | * Returns all tweens that are in the masterList. Tweens are automatically removed from the | ||
| 1084 | * masterList when they complete and are not attached to a timeline that has | ||
| 1085 | * autoRemoveChildren set to true. | ||
| 1086 | * | ||
| 1087 | * @return Array of TweenLite and/or TweenMax instances | ||
| 1088 | */ | ||
| 1089 | public static function getAllTweens():Array { | ||
| 1090 | var ml:Dictionary = masterList; //speeds things up slightly | ||
| 1091 | var cnt:uint = 0; | ||
| 1092 | var toReturn:Array = [], a:Array, i:int; | ||
| 1093 | for each (a in ml) { | ||
| 1094 | i = a.length; | ||
| 1095 | while (--i > -1) { | ||
| 1096 | if (!TweenLite(a[i]).gc) { | ||
| 1097 | toReturn[cnt++] = a[i]; | ||
| 1098 | } | ||
| 1099 | } | ||
| 1100 | } | ||
| 1101 | return toReturn; | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | /** | ||
| 1105 | * Kills all tweens and/or delayedCalls/callbacks, optionally forcing them to completion first. | ||
| 1106 | * | ||
| 1107 | * @param complete Determines whether or not the tweens/delayedCalls/callbacks should be forced to completion before being killed. | ||
| 1108 | * @param tweens If true, all tweens will be killed | ||
| 1109 | * @param delayedCalls If true, all delayedCalls will be killed. TimelineMax callbacks are treated the same as delayedCalls. | ||
| 1110 | */ | ||
| 1111 | public static function killAll(complete:Boolean=false, tweens:Boolean=true, delayedCalls:Boolean=true):void { | ||
| 1112 | var a:Array = getAllTweens(); | ||
| 1113 | var isDC:Boolean; //is delayedCall | ||
| 1114 | var i:int = a.length; | ||
| 1115 | while (--i > -1) { | ||
| 1116 | isDC = (a[i].target == a[i].vars.onComplete); | ||
| 1117 | if (isDC == delayedCalls || isDC != tweens) { | ||
| 1118 | if (complete) { | ||
| 1119 | a[i].complete(false); | ||
| 1120 | } else { | ||
| 1121 | a[i].setEnabled(false, false); | ||
| 1122 | } | ||
| 1123 | } | ||
| 1124 | } | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | /** | ||
| 1128 | * Kills all tweens of the children of a particular DisplayObjectContainer, optionally forcing them to completion first. | ||
| 1129 | * | ||
| 1130 | * @param parent The DisplayObjectContainer whose children should no longer be affected by any tweens. | ||
| 1131 | * @param complete Determines whether or not the tweens should be forced to completion before being killed. | ||
| 1132 | */ | ||
| 1133 | public static function killChildTweensOf(parent:DisplayObjectContainer, complete:Boolean=false):void { | ||
| 1134 | var a:Array = getAllTweens(); | ||
| 1135 | var curTarget:Object, curParent:DisplayObjectContainer; | ||
| 1136 | var i:int = a.length; | ||
| 1137 | while (--i > -1) { | ||
| 1138 | curTarget = a[i].target; | ||
| 1139 | if (curTarget is DisplayObject) { | ||
| 1140 | curParent = curTarget.parent; | ||
| 1141 | while (curParent) { | ||
| 1142 | if (curParent == parent) { | ||
| 1143 | if (complete) { | ||
| 1144 | a[i].complete(false); | ||
| 1145 | } else { | ||
| 1146 | a[i].setEnabled(false, false); | ||
| 1147 | } | ||
| 1148 | } | ||
| 1149 | curParent = curParent.parent; | ||
| 1150 | } | ||
| 1151 | } | ||
| 1152 | } | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | /** | ||
| 1156 | * Pauses all tweens and/or delayedCalls/callbacks. | ||
| 1157 | * | ||
| 1158 | * @param tweens If true, all tweens will be paused. | ||
| 1159 | * @param delayedCalls If true, all delayedCalls will be paused. TimelineMax callbacks are treated the same as delayedCalls. | ||
| 1160 | */ | ||
| 1161 | public static function pauseAll(tweens:Boolean=true, delayedCalls:Boolean=true):void { | ||
| 1162 | changePause(true, tweens, delayedCalls); | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | /** | ||
| 1166 | * Resumes all paused tweens and/or delayedCalls/callbacks. | ||
| 1167 | * | ||
| 1168 | * @param tweens If true, all tweens will be resumed. | ||
| 1169 | * @param delayedCalls If true, all delayedCalls will be resumed. TimelineMax callbacks are treated the same as delayedCalls. | ||
| 1170 | */ | ||
| 1171 | public static function resumeAll(tweens:Boolean=true, delayedCalls:Boolean=true):void { | ||
| 1172 | changePause(false, tweens, delayedCalls); | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | /** | ||
| 1176 | * @private | ||
| 1177 | * Changes the paused state of all tweens and/or delayedCalls/callbacks | ||
| 1178 | * | ||
| 1179 | * @param pause Desired paused state | ||
| 1180 | * @param tweens If true, all tweens will be affected. | ||
| 1181 | * @param delayedCalls If true, all delayedCalls will be affected. TimelineMax callbacks are treated the same as delayedCalls. | ||
| 1182 | */ | ||
| 1183 | private static function changePause(pause:Boolean, tweens:Boolean=true, delayedCalls:Boolean=false):void { | ||
| 1184 | var a:Array = getAllTweens(); | ||
| 1185 | var isDC:Boolean; //is delayedCall | ||
| 1186 | var i:int = a.length; | ||
| 1187 | while (--i > -1) { | ||
| 1188 | isDC = (TweenLite(a[i]).target == TweenLite(a[i]).vars.onComplete); | ||
| 1189 | if (isDC == delayedCalls || isDC != tweens) { | ||
| 1190 | TweenCore(a[i]).paused = pause; | ||
| 1191 | } | ||
| 1192 | } | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | |||
| 1196 | //---- GETTERS / SETTERS ---------------------------------------------------------------------------------------------------------- | ||
| 1197 | |||
| 1198 | |||
| 1199 | /** | ||
| 1200 | * Value between 0 and 1 indicating the progress of the tween according to its <code>duration</code> | ||
| 1201 | * where 0 is at the beginning, 0.5 is halfway finished, and 1 is finished. <code>totalProgress</code>, | ||
| 1202 | * by contrast, describes the overall progress according to the tween's <code>totalDuration</code> | ||
| 1203 | * which includes repeats and repeatDelays (if there are any). For example, if a TweenMax instance | ||
| 1204 | * is set to repeat once, at the end of the first cycle <code>totalProgress</code> would only be 0.5 | ||
| 1205 | * whereas <code>currentProgress</code> would be 1. If you tracked both properties over the course of the | ||
| 1206 | * tween, you'd see <code>currentProgress</code> go from 0 to 1 twice (once for each cycle) in the same | ||
| 1207 | * time it takes the <code>totalProgress</code> property to go from 0 to 1 once. | ||
| 1208 | **/ | ||
| 1209 | public function get currentProgress():Number { | ||
| 1210 | return this.cachedTime / this.duration; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | public function set currentProgress(n:Number):void { | ||
| 1214 | if (_cyclesComplete == 0) { | ||
| 1215 | setTotalTime(this.duration * n, false); | ||
| 1216 | } else { | ||
| 1217 | setTotalTime(this.duration * n + (_cyclesComplete * this.cachedDuration), false); | ||
| 1218 | } | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | /** | ||
| 1222 | * Value between 0 and 1 indicating the overall progress of the tween according to its <code>totalDuration</code> | ||
| 1223 | * where 0 is at the beginning, 0.5 is halfway finished, and 1 is finished. <code>currentProgress</code>, | ||
| 1224 | * by contrast, describes the progress according to the tween's <code>duration</code> which does not | ||
| 1225 | * include repeats and repeatDelays. For example, if a TweenMax instance is set to repeat | ||
| 1226 | * once, at the end of the first cycle <code>totalProgress</code> would only be 0.5 | ||
| 1227 | * whereas <code>currentProgress</code> would be 1. If you tracked both properties over the course of the | ||
| 1228 | * tween, you'd see <code>currentProgress</code> go from 0 to 1 twice (once for each cycle) in the same | ||
| 1229 | * time it takes the <code>totalProgress</code> property to go from 0 to 1 once. | ||
| 1230 | **/ | ||
| 1231 | public function get totalProgress():Number { | ||
| 1232 | return this.cachedTotalTime / this.totalDuration; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | public function set totalProgress(n:Number):void { | ||
| 1236 | setTotalTime(this.totalDuration * n, false); | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | /** | ||
| 1240 | * Most recently rendered time (or frame for frames-based timelines) according to the tween's | ||
| 1241 | * duration. <code>totalTime</code>, by contrast, is based on the <code>totalDuration</code> which includes repeats and repeatDelays. | ||
| 1242 | * For example, if a TweenMax instance has a duration of 5 a repeat of 1 (meaning its | ||
| 1243 | * <code>totalDuration</code> is 10), at the end of the second cycle, <code>currentTime</code> would be 5 whereas <code>totalTime</code> | ||
| 1244 | * would be 10. If you tracked both properties over the course of the tween, you'd see <code>currentTime</code> | ||
| 1245 | * go from 0 to 5 twice (one for each cycle) in the same time it takes <code>totalTime</code> go from 0 to 10. | ||
| 1246 | */ | ||
| 1247 | override public function set currentTime(n:Number):void { | ||
| 1248 | if (_cyclesComplete == 0) { | ||
| 1249 | //no change needed | ||
| 1250 | } else if (this.yoyo && (_cyclesComplete % 2 == 1)) { | ||
| 1251 | n = (this.duration - n) + (_cyclesComplete * (this.cachedDuration + _repeatDelay)); | ||
| 1252 | } else { | ||
| 1253 | n += (_cyclesComplete * (this.duration + _repeatDelay)); | ||
| 1254 | } | ||
| 1255 | setTotalTime(n, false); | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | /** | ||
| 1259 | * Duration of the tween in seconds (or frames for frames-based timelines) including any repeats | ||
| 1260 | * or repeatDelays. <code>duration</code>, by contrast, does NOT include repeats and repeatDelays. | ||
| 1261 | **/ | ||
| 1262 | override public function get totalDuration():Number { | ||
| 1263 | if (this.cacheIsDirty) { | ||
| 1264 | //instead of Infinity, we use 999999999999 so that we can accommodate reverses | ||
| 1265 | this.cachedTotalDuration = (_repeat == -1) ? 999999999999 : this.cachedDuration * (_repeat + 1) + (_repeatDelay * _repeat); | ||
| 1266 | this.cacheIsDirty = false; | ||
| 1267 | } | ||
| 1268 | return this.cachedTotalDuration; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | override public function set totalDuration(n:Number):void { | ||
| 1272 | if (_repeat == -1) { | ||
| 1273 | return; | ||
| 1274 | } | ||
| 1275 | this.duration = (n - (_repeat * _repeatDelay)) / (_repeat + 1); | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | /** Multiplier describing the speed of the timeline where 1 is normal speed, 0.5 is half-speed, 2 is double speed, etc. **/ | ||
| 1279 | public function get timeScale():Number { | ||
| 1280 | return this.cachedTimeScale; | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | public function set timeScale(n:Number):void { | ||
| 1284 | if (n == 0) { //can't allow zero because it'll throw the math off | ||
| 1285 | n = 0.0001; | ||
| 1286 | } | ||
| 1287 | var tlTime:Number = (_pauseTime || _pauseTime == 0) ? _pauseTime : this.timeline.cachedTotalTime; | ||
| 1288 | this.cachedStartTime = tlTime - ((tlTime - this.cachedStartTime) * this.cachedTimeScale / n); | ||
| 1289 | this.cachedTimeScale = n; | ||
| 1290 | setDirtyCache(false); | ||
| 1291 | } | ||
| 1292 | |||
| 1293 | /** Number of times that the tween should repeat; -1 repeats indefinitely. **/ | ||
| 1294 | public function get repeat():int { | ||
| 1295 | return _repeat; | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | public function set repeat(n:int):void { | ||
| 1299 | _repeat = n; | ||
| 1300 | setDirtyCache(true); | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | /** Amount of time in seconds (or frames for frames-based tweens) between repeats **/ | ||
| 1304 | public function get repeatDelay():Number { | ||
| 1305 | return _repeatDelay; | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | public function set repeatDelay(n:Number):void { | ||
| 1309 | _repeatDelay = n; | ||
| 1310 | setDirtyCache(true); | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | /** Multiplier describing the speed of the root timelines where 1 is normal speed, 0.5 is half-speed, 2 is double speed, etc. The lowest globalTimeScale possible is 0.0001. **/ | ||
| 1314 | public static function get globalTimeScale():Number { | ||
| 1315 | return (TweenLite.rootTimeline == null) ? 1 : TweenLite.rootTimeline.cachedTimeScale; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | public static function set globalTimeScale(n:Number):void { | ||
| 1319 | if (n == 0) { //can't allow zero because it'll throw the math off | ||
| 1320 | n = 0.0001; | ||
| 1321 | } | ||
| 1322 | if (TweenLite.rootTimeline == null) { | ||
| 1323 | TweenLite.to({}, 0, {}); //forces initialization in case globalTimeScale is set before any tweens are created. | ||
| 1324 | } | ||
| 1325 | var tl:SimpleTimeline = TweenLite.rootTimeline; | ||
| 1326 | var curTime:Number = (getTimer() * 0.001) | ||
| 1327 | tl.cachedStartTime = curTime - ((curTime - tl.cachedStartTime) * tl.cachedTimeScale / n); | ||
| 1328 | tl = TweenLite.rootFramesTimeline; | ||
| 1329 | curTime = TweenLite.rootFrame; | ||
| 1330 | tl.cachedStartTime = curTime - ((curTime - tl.cachedStartTime) * tl.cachedTimeScale / n); | ||
| 1331 | TweenLite.rootFramesTimeline.cachedTimeScale = TweenLite.rootTimeline.cachedTimeScale = n; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | |||
| 1335 | } | ||
| 1336 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.05 | ||
| 3 | * DATE: 2010-05-11 | ||
| 4 | * AS3 (AS2 is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenNano.com | ||
| 6 | **/ | ||
| 7 | package com.greensock { | ||
| 8 | import flash.display.*; | ||
| 9 | import flash.events.*; | ||
| 10 | import flash.utils.*; | ||
| 11 | /** | ||
| 12 | * TweenNano is a super-lightweight (1.6k in AS3 and 2k in AS2) version of <a href="http://www.TweenLite.com">TweenLite</a> | ||
| 13 | * and is only recommended for situations where you absolutely cannot afford the extra 3.1k (4.7k total) that the normal | ||
| 14 | * TweenLite engine would cost and your project doesn't require any plugins. Normally, it is much better to use | ||
| 15 | * TweenLite because of the additional flexibility it provides via plugins and its compatibility with TimelineLite and TimelineMax. | ||
| 16 | * TweenNano can do everything TweenLite can do with the following exceptions: | ||
| 17 | * <ul> | ||
| 18 | * <li><b> No Plugins </b>- One of the great things about TweenLite is that you can activate | ||
| 19 | * plugins in order to add features (like autoAlpha, tint, blurFilter, etc.). TweenNano, however, | ||
| 20 | * doesn't work with plugins. </li> | ||
| 21 | * | ||
| 22 | * <li><b> Incompatible with TimelineLite and TimelineMax </b>- Complex sequencing and management of groups of | ||
| 23 | * tweens can be much easier with TimelineLite and TimelineMax, but TweenNano instances cannot be inserted into | ||
| 24 | * TimelineLite or TimelineMax instances.</li> | ||
| 25 | * | ||
| 26 | * <li><b> Slight speed decrease </b>- Under very heavy loads, TweenNano won't perform quite as well as TweenLite, but | ||
| 27 | * it is extremely unlikely that you'd notice unless you're tweening thousands of objects simultaneously.</li> | ||
| 28 | * | ||
| 29 | * <li><b> Fewer overwrite modes </b>- You can either overwrite all or none of the existing tweens of the same | ||
| 30 | * object (overwrite:true or overwrite:false) in TweenNano. TweenLite, however, can use OverwriteManager to expand | ||
| 31 | * its capabilities and use modes like AUTO, CONCURRENT, PREEXISTING, and ALL_ONSTART | ||
| 32 | * (see <a href="http://www.greensock.com/overwritemanager/">http://www.greensock.com/overwritemanager/</a> | ||
| 33 | * for details).</li> | ||
| 34 | * | ||
| 35 | * <li><b>Compared to TweenLite, TweenNano is missing the following methods/properties:</b> | ||
| 36 | * <ul> | ||
| 37 | * <li>pause()</li> | ||
| 38 | * <li>play()</li> | ||
| 39 | * <li>resume()</li> | ||
| 40 | * <li>restart()</li> | ||
| 41 | * <li>reverse()</li> | ||
| 42 | * <li>invalidate()</li> | ||
| 43 | * <li>onStart</li> | ||
| 44 | * <li>onInit</li> | ||
| 45 | * <li>defaultEase</li> | ||
| 46 | * <li>easeParams</li> | ||
| 47 | * <li>currentTime</li> | ||
| 48 | * <li>startTime</li> | ||
| 49 | * <li>totalTime</li> | ||
| 50 | * <li>paused</li> | ||
| 51 | * <li>reversed</li> | ||
| 52 | * <li>totalDuration</li> | ||
| 53 | * </ul> | ||
| 54 | * </li> | ||
| 55 | * </ul> | ||
| 56 | * | ||
| 57 | * <hr/> | ||
| 58 | * <b>SPECIAL PROPERTIES:</b> | ||
| 59 | * <br /><br /> | ||
| 60 | * | ||
| 61 | * Any of the following special properties can optionally be passed in through the vars object (the third parameter): | ||
| 62 | * | ||
| 63 | * <ul> | ||
| 64 | * <li><b> delay : Number</b> Amount of delay in seconds (or frames for frames-based tweens) before the tween should begin.</li> | ||
| 65 | * | ||
| 66 | * <li><b> useFrames : Boolean</b> If useFrames is set to true, the tweens's timing mode will be based on frames. | ||
| 67 | * Otherwise, it will be based on seconds/time.</li> | ||
| 68 | * | ||
| 69 | * <li><b> ease : Function</b> Use any standard easing equation to control the rate of change. For example, | ||
| 70 | * <code>Elastic.easeOut</code>. The Default is Regular.easeOut.</li> | ||
| 71 | * | ||
| 72 | * <li><b> onUpdate : Function</b> A function that should be called every time the tween's time/position is updated | ||
| 73 | * (on every frame while the timeline is active)</li> | ||
| 74 | * | ||
| 75 | * <li><b> onUpdateParams : Array</b> An Array of parameters to pass the onUpdate function</li> | ||
| 76 | * | ||
| 77 | * <li><b> onComplete : Function</b> A function that should be called when the tween has finished </li> | ||
| 78 | * | ||
| 79 | * <li><b> onCompleteParams : Array</b> An Array of parameters to pass the onComplete function.</li> | ||
| 80 | * | ||
| 81 | * <li><b> immediateRender : Boolean</b> Normally when you create a from() tween, it renders the starting state immediately even | ||
| 82 | * if you define a delay which in typical "animate in" scenarios is very desirable, but | ||
| 83 | * if you prefer to override this behavior and have the from() tween render only after any | ||
| 84 | * delay has elapsed, set <code>immediateRender</code> to false. </li> | ||
| 85 | * | ||
| 86 | * <li><b> overwrite : Boolean</b> Controls how other tweens of the same object are handled when this tween is created. Here are the options: | ||
| 87 | * <ul> | ||
| 88 | * <li><b> false (NONE):</b> No tweens are overwritten. This is the fastest mode, but you need to be careful not | ||
| 89 | * to create any tweens with overlapping properties of the same object that run at the same time, | ||
| 90 | * otherwise they'll conflict with each other. <br /><code> | ||
| 91 | * TweenNano.to(mc, 1, {x:100, y:200});<br /> | ||
| 92 | * TweenNano.to(mc, 1, {x:300, delay:2, overwrite:false}); //does NOT overwrite the previous tween.</code></li> | ||
| 93 | * | ||
| 94 | * <li><b> true (ALL_IMMEDIATE):</b> This is the default mode in TweenNano. All tweens of the same target | ||
| 95 | * are completely overwritten immediately when the tween is created, regardless of whether or | ||
| 96 | * not any of the properties overlap. <br /><code> | ||
| 97 | * TweenNano.to(mc, 1, {x:100, y:200});<br /> | ||
| 98 | * TweenNano.to(mc, 1, {x:300, delay:2, overwrite:true}); //immediately overwrites the previous tween</code></li> | ||
| 99 | * </ul></li> | ||
| 100 | * </ul> | ||
| 101 | * | ||
| 102 | * <b>EXAMPLES:</b> <br /><br /> | ||
| 103 | * | ||
| 104 | * Tween the the MovieClip "mc" to an alpha value of 0.5 (50% transparent) and an x-coordinate of 120 | ||
| 105 | * over the course of 1.5 seconds like so:<br /><br /> | ||
| 106 | * | ||
| 107 | * <code> | ||
| 108 | * import com.greensock.TweenNano;<br /><br /> | ||
| 109 | * TweenNano.to(mc, 1.5, {alpha:0.5, x:120}); | ||
| 110 | * </code><br /><br /> | ||
| 111 | * | ||
| 112 | * To tween the "mc" MovieClip's alpha property to 0.5, its x property to 120 using the <code>Back.easeOut</code> easing | ||
| 113 | * function, delay starting the whole tween by 2 seconds, and then call a function named "onFinishTween" when it | ||
| 114 | * has completed (it will have a duration of 5 seconds) and pass a few parameters to that function (a value of | ||
| 115 | * 5 and a reference to the mc), you'd do so like:<br /><br /> | ||
| 116 | * | ||
| 117 | * <code> | ||
| 118 | * import com.greensock.TweenNano;<br /> | ||
| 119 | * import com.greensock.easing.Back;<br /><br /> | ||
| 120 | * | ||
| 121 | * TweenNano.to(mc, 5, {alpha:0.5, x:120, ease:Back.easeOut, delay:2, onComplete:onFinishTween, onCompleteParams:[5, mc]});<br /> | ||
| 122 | * function onFinishTween(param1:Number, param2:MovieClip):void {<br /> | ||
| 123 | * trace("The tween has finished! param1 = " + param1 + ", and param2 = " + param2);<br /> | ||
| 124 | * } | ||
| 125 | * </code><br /><br /> | ||
| 126 | * | ||
| 127 | * If you have a MovieClip on the stage that is already in it's end position and you just want to animate it into | ||
| 128 | * place over 5 seconds (drop it into place by changing its y property to 100 pixels higher on the screen and | ||
| 129 | * dropping it from there), you could:<br /><br /> | ||
| 130 | * | ||
| 131 | * <code> | ||
| 132 | * import com.greensock.TweenNano;<br /> | ||
| 133 | * import com.greensock.easing.Elastic;<br /><br /> | ||
| 134 | * | ||
| 135 | * TweenNano.from(mc, 5, {y:"-100", ease:Elastic.easeOut}); | ||
| 136 | * </code><br /><br /> | ||
| 137 | * | ||
| 138 | * <b>NOTES:</b><br /><br /> | ||
| 139 | * <ul> | ||
| 140 | * <li> The base TweenNano class adds about 1.6k to your Flash file.</li> | ||
| 141 | * | ||
| 142 | * <li> Passing values as Strings will make the tween relative to the current value. For example, if you do | ||
| 143 | * <code>TweenNano.to(mc, 2, {x:"-20"});</code> it'll move the mc.x to the left 20 pixels which is the same as doing | ||
| 144 | * <code>TweenNano.to(mc, 2, {x:mc.x - 20});</code> You could also cast it like: <code>TweenNano.to(mc, 2, {x:String(myVariable)});</code></li> | ||
| 145 | * | ||
| 146 | * <li> Kill all tweens for a particular object anytime with the <code>TweenNano.killTweensOf(mc); </code></li> | ||
| 147 | * | ||
| 148 | * <li> You can kill all delayedCalls to a particular function using <code>TweenNano.killTweensOf(myFunction);</code> | ||
| 149 | * This can be helpful if you want to preempt a call.</li> | ||
| 150 | * | ||
| 151 | * <li> If some of your tweens don't appear to be working, read about the <code>overwrite</code> special property | ||
| 152 | * above - it is most likely an overwriting issue that could be solved by adding <code>overwrite:false</code> to your vars object.</li> | ||
| 153 | * | ||
| 154 | * <li> Use the <code>TweenNano.from()</code> method to animate things into place. For example, if you have things set up on | ||
| 155 | * the stage in the spot where they should end up, and you just want to animate them into place, you can | ||
| 156 | * pass in the beginning x and/or y and/or alpha (or whatever properties you want).</li> | ||
| 157 | * | ||
| 158 | * <li> If you find this class useful, please consider joining Club GreenSock which not only helps to sustain | ||
| 159 | * ongoing development, but also gets you bonus plugins, classes and other benefits that are ONLY available | ||
| 160 | * to members. Learn more at <a href="http://www.greensock.com/club/">http://www.greensock.com/club/</a></li> | ||
| 161 | * </ul> | ||
| 162 | * | ||
| 163 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 164 | * | ||
| 165 | * @author Jack Doyle, jack@greensock.com | ||
| 166 | */ | ||
| 167 | public class TweenNano { | ||
| 168 | /** @private **/ | ||
| 169 | protected static var _time:Number; | ||
| 170 | /** @private **/ | ||
| 171 | protected static var _frame:uint; | ||
| 172 | /** @private Holds references to all our tweens based on their targets (an Array for each target) **/ | ||
| 173 | protected static var _masterList:Dictionary = new Dictionary(false); | ||
| 174 | /** @private A reference to the Shape that we use to drive all our ENTER_FRAME events. **/ | ||
| 175 | protected static var _shape:Shape = new Shape(); | ||
| 176 | /** @private Indicates whether or not the TweenNano class has been initted. **/ | ||
| 177 | protected static var _tnInitted:Boolean; | ||
| 178 | /** @private **/ | ||
| 179 | protected static var _reservedProps:Object = {ease:1, delay:1, useFrames:1, overwrite:1, onComplete:1, onCompleteParams:1, runBackwards:1, immediateRender:1, onUpdate:1, onUpdateParams:1}; | ||
| 180 | |||
| 181 | /** Duration of the tween in seconds (or in frames if "useFrames" is true). **/ | ||
| 182 | public var duration:Number; | ||
| 183 | /** Stores variables (things like "alpha", "y" or whatever we're tweening, as well as special properties like "onComplete"). **/ | ||
| 184 | public var vars:Object; | ||
| 185 | /** @private Start time in seconds (or frames for frames-based tweens) **/ | ||
| 186 | public var startTime:Number; | ||
| 187 | /** Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. **/ | ||
| 188 | public var target:Object; | ||
| 189 | /** @private Indicates whether or not the tween is currently active **/ | ||
| 190 | public var active:Boolean; | ||
| 191 | /** @private Flagged for garbage collection **/ | ||
| 192 | public var gc:Boolean; | ||
| 193 | /** Indicates that frames should be used instead of seconds for timing purposes. So if useFrames is true and the tween's duration is 10, it would mean that the tween should take 10 frames to complete, not 10 seconds. **/ | ||
| 194 | public var useFrames:Boolean; | ||
| 195 | /** @private result of _ease(this.time, 0, 1, this.duration). Usually between 0 and 1, but not always (like with Elastic.easeOut). **/ | ||
| 196 | public var ratio:Number = 0; | ||
| 197 | |||
| 198 | /** @private Easing method to use which determines how the values animate over time. Examples are Elastic.easeOut and Strong.easeIn. Many are found in the fl.motion.easing package or com.greensock.easing. **/ | ||
| 199 | protected var _ease:Function; | ||
| 200 | /** @private Indicates whether or not init() has been called (where all the tween property start/end value information is recorded) **/ | ||
| 201 | protected var _initted:Boolean; | ||
| 202 | /** @private Contains parsed data for each property that's being tweened (property name, start, and change) **/ | ||
| 203 | protected var _propTweens:Array; | ||
| 204 | |||
| 205 | /** | ||
| 206 | * Constructor | ||
| 207 | * | ||
| 208 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 209 | * @param duration Duration in seconds (or in frames if "useFrames" is true) | ||
| 210 | * @param vars An object containing the end values of the properties you're tweening, like {x:100, y:50}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 211 | */ | ||
| 212 | public function TweenNano(target:Object, duration:Number, vars:Object) { | ||
| 213 | if (!_tnInitted) { | ||
| 214 | _time = getTimer() * 0.001; | ||
| 215 | _frame = 0; | ||
| 216 | _shape.addEventListener(Event.ENTER_FRAME, updateAll, false, 0, true); | ||
| 217 | _tnInitted = true; | ||
| 218 | } | ||
| 219 | this.vars = vars; | ||
| 220 | this.duration = duration; | ||
| 221 | this.active = Boolean(duration == 0 && this.vars.delay == 0 && this.vars.immediateRender != false); | ||
| 222 | this.target = target; | ||
| 223 | if (typeof(this.vars.ease) != "function") { | ||
| 224 | _ease = TweenNano.easeOut; | ||
| 225 | } else { | ||
| 226 | _ease = this.vars.ease; | ||
| 227 | } | ||
| 228 | _propTweens = []; | ||
| 229 | this.useFrames = Boolean(vars.useFrames == true); | ||
| 230 | var delay:Number = ("delay" in this.vars) ? Number(this.vars.delay) : 0; | ||
| 231 | this.startTime = (this.useFrames) ? _frame + delay : _time + delay; | ||
| 232 | |||
| 233 | var a:Array = _masterList[target]; | ||
| 234 | if (a == null || int(this.vars.overwrite) == 1 || this.vars.overwrite == null) { | ||
| 235 | _masterList[target] = [this]; | ||
| 236 | } else { | ||
| 237 | a[a.length] = this; | ||
| 238 | } | ||
| 239 | |||
| 240 | if (this.vars.immediateRender == true || this.active) { | ||
| 241 | renderTime(0); | ||
| 242 | } | ||
| 243 | } | ||
| 244 | |||
| 245 | /** | ||
| 246 | * @private | ||
| 247 | * Initializes the property tweens, determining their start values and amount of change. | ||
| 248 | * Also triggers overwriting if necessary and sets the _hasUpdate variable. | ||
| 249 | */ | ||
| 250 | public function init():void { | ||
| 251 | for (var p:String in this.vars) { | ||
| 252 | if (!(p in _reservedProps)) { | ||
| 253 | _propTweens[_propTweens.length] = [p, this.target[p], (typeof(this.vars[p]) == "number") ? this.vars[p] - this.target[p] : Number(this.vars[p])]; //[property, start, change] | ||
| 254 | } | ||
| 255 | } | ||
| 256 | if (this.vars.runBackwards) { | ||
| 257 | var pt:Array; | ||
| 258 | var i:int = _propTweens.length; | ||
| 259 | while (--i > -1) { | ||
| 260 | pt = _propTweens[i]; | ||
| 261 | pt[1] += pt[2]; | ||
| 262 | pt[2] = -pt[2]; | ||
| 263 | } | ||
| 264 | } | ||
| 265 | _initted = true; | ||
| 266 | } | ||
| 267 | |||
| 268 | /** | ||
| 269 | * Renders the tween at a particular time (or frame number for frames-based tweens) | ||
| 270 | * WITHOUT changing its startTime, meaning if the tween is in progress when you call | ||
| 271 | * renderTime(), it will not adjust the tween's timing to continue from the new time. | ||
| 272 | * The time is based simply on the overall duration. For example, if a tween's duration | ||
| 273 | * is 3, renderTime(1.5) would render it at the halfway finished point. | ||
| 274 | * | ||
| 275 | * @param time time (or frame number for frames-based tweens) to render. | ||
| 276 | */ | ||
| 277 | public function renderTime(time:Number):void { | ||
| 278 | if (!_initted) { | ||
| 279 | init(); | ||
| 280 | } | ||
| 281 | var pt:Array, i:int = _propTweens.length; | ||
| 282 | if (time >= this.duration) { | ||
| 283 | time = this.duration; | ||
| 284 | this.ratio = 1; | ||
| 285 | } else if (time <= 0) { | ||
| 286 | this.ratio = 0; | ||
| 287 | } else { | ||
| 288 | this.ratio = _ease(time, 0, 1, this.duration); | ||
| 289 | } | ||
| 290 | while (--i > -1) { | ||
| 291 | pt = _propTweens[i]; | ||
| 292 | this.target[pt[0]] = pt[1] + (this.ratio * pt[2]); | ||
| 293 | } | ||
| 294 | if (this.vars.onUpdate) { | ||
| 295 | this.vars.onUpdate.apply(null, this.vars.onUpdateParams); | ||
| 296 | } | ||
| 297 | if (time == this.duration) { | ||
| 298 | complete(true); | ||
| 299 | } | ||
| 300 | } | ||
| 301 | |||
| 302 | /** | ||
| 303 | * Forces the tween to completion. | ||
| 304 | * | ||
| 305 | * @param skipRender To skip rendering the final state of the tween, set skipRender to true. | ||
| 306 | */ | ||
| 307 | public function complete(skipRender:Boolean=false):void { | ||
| 308 | if (!skipRender) { | ||
| 309 | renderTime(this.duration); | ||
| 310 | return; | ||
| 311 | } | ||
| 312 | kill(); | ||
| 313 | if (this.vars.onComplete) { | ||
| 314 | this.vars.onComplete.apply(null, this.vars.onCompleteParams); | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | /** Kills the tween, stopping it immediately. **/ | ||
| 319 | public function kill():void { | ||
| 320 | this.gc = true; | ||
| 321 | this.active = false; | ||
| 322 | } | ||
| 323 | |||
| 324 | |||
| 325 | //---- STATIC FUNCTIONS ------------------------------------------------------------------------- | ||
| 326 | |||
| 327 | /** | ||
| 328 | * Static method for creating a TweenNano instance which can be more intuitive for some developers | ||
| 329 | * and shields them from potential garbage collection issues that could arise when assigning a | ||
| 330 | * tween instance to a variable that persists. The following lines of code all produce exactly | ||
| 331 | * the same result: <br /><br /><code> | ||
| 332 | * | ||
| 333 | * var myTween:TweenNano = new TweenNano(mc, 1, {x:100}); <br /> | ||
| 334 | * TweenNano.to(mc, 1, {x:100}); <br /> | ||
| 335 | * var myTween:TweenNano = TweenNano.to(mc, 1, {x:100});</code> | ||
| 336 | * | ||
| 337 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 338 | * @param duration Duration in seconds (or frames if "useFrames" is true) | ||
| 339 | * @param vars An object containing the end values of the properties you're tweening, like {x:100, y:50}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 340 | * @return TweenNano instance | ||
| 341 | */ | ||
| 342 | public static function to(target:Object, duration:Number, vars:Object):TweenNano { | ||
| 343 | return new TweenNano(target, duration, vars); | ||
| 344 | } | ||
| 345 | |||
| 346 | /** | ||
| 347 | * Static method for creating a TweenNano instance that tweens in the opposite direction | ||
| 348 | * compared to a TweenNano.to() tween. In other words, you define the START values in the | ||
| 349 | * vars object instead of the end values, and the tween will use the current values as | ||
| 350 | * the end values. This can be very useful for animating things into place on the stage | ||
| 351 | * because you can build them in their end positions and do some simple TweenNano.from() | ||
| 352 | * calls to animate them into place. <b>NOTE:</b> By default, <code>immediateRender</code> | ||
| 353 | * is <code>true</code> in from() tweens, meaning that they immediately render their starting state | ||
| 354 | * regardless of any delay that is specified. You can override this behavior by passing | ||
| 355 | * <code>immediateRender:false</code> in the <code>vars</code> object so that it will wait to | ||
| 356 | * render until the tween actually begins. To illustrate the default behavior, the following code | ||
| 357 | * will immediately set the <code>alpha</code> of <code>mc</code> to 0 and then wait 2 seconds | ||
| 358 | * before tweening the <code>alpha</code> back to 1 over the course of 1.5 seconds:<br /><br /><code> | ||
| 359 | * | ||
| 360 | * TweenNano.from(mc, 1.5, {alpha:0, delay:2});</code> | ||
| 361 | * | ||
| 362 | * @param target Target object whose properties this tween affects. This can be ANY object, not just a DisplayObject. | ||
| 363 | * @param duration Duration in seconds (or frames if "useFrames" is true) | ||
| 364 | * @param vars An object containing the start values of the properties you're tweening like {x:100, y:50}. It can also contain special properties like "onComplete", "ease", "delay", etc. | ||
| 365 | * @return TweenNano instance | ||
| 366 | */ | ||
| 367 | public static function from(target:Object, duration:Number, vars:Object):TweenNano { | ||
| 368 | vars.runBackwards = true; | ||
| 369 | if (!("immediateRender" in vars)) { | ||
| 370 | vars.immediateRender = true; | ||
| 371 | } | ||
| 372 | return new TweenNano(target, duration, vars); | ||
| 373 | } | ||
| 374 | |||
| 375 | /** | ||
| 376 | * Provides a simple way to call a function after a set amount of time (or frames). You can | ||
| 377 | * optionally pass any number of parameters to the function too. For example:<br /><br /><code> | ||
| 378 | * | ||
| 379 | * TweenNano.delayedCall(1, myFunction, ["param1", 2]); <br /> | ||
| 380 | * function myFunction(param1:String, param2:Number):void { <br /> | ||
| 381 | * trace("called myFunction and passed params: " + param1 + ", " + param2); <br /> | ||
| 382 | * } </code> | ||
| 383 | * | ||
| 384 | * @param delay Delay in seconds (or frames if "useFrames" is true) before the function should be called | ||
| 385 | * @param onComplete Function to call | ||
| 386 | * @param onCompleteParams An Array of parameters to pass the function. | ||
| 387 | * @param useFrames If the delay should be measured in frames instead of seconds, set useFrames to true (default is false) | ||
| 388 | * @return TweenNano instance | ||
| 389 | */ | ||
| 390 | public static function delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array=null, useFrames:Boolean=false):TweenNano { | ||
| 391 | return new TweenNano(onComplete, 0, {delay:delay, onComplete:onComplete, onCompleteParams:onCompleteParams, useFrames:useFrames, overwrite:0}); | ||
| 392 | } | ||
| 393 | |||
| 394 | /** | ||
| 395 | * @private | ||
| 396 | * Updates active tweens and activates those whose startTime is before the _time/_frame. | ||
| 397 | * | ||
| 398 | * @param e ENTER_FRAME Event | ||
| 399 | */ | ||
| 400 | public static function updateAll(e:Event=null):void { | ||
| 401 | _frame++; | ||
| 402 | _time = getTimer() * 0.001; | ||
| 403 | var ml:Dictionary = _masterList, a:Array, tgt:Object, i:int, t:Number, tween:TweenNano; | ||
| 404 | for (tgt in ml) { | ||
| 405 | a = ml[tgt]; | ||
| 406 | i = a.length; | ||
| 407 | while (--i > -1) { | ||
| 408 | tween = a[i]; | ||
| 409 | t = (tween.useFrames) ? _frame : _time; | ||
| 410 | if (tween.active || (!tween.gc && t >= tween.startTime)) { | ||
| 411 | tween.renderTime(t - tween.startTime); | ||
| 412 | } else if (tween.gc) { | ||
| 413 | a.splice(i, 1); | ||
| 414 | } | ||
| 415 | } | ||
| 416 | if (a.length == 0) { | ||
| 417 | delete ml[tgt]; | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | /** | ||
| 423 | * Kills all the tweens of a particular object, optionally forcing them to completion too. | ||
| 424 | * | ||
| 425 | * @param target Object whose tweens should be immediately killed | ||
| 426 | * @param complete Indicates whether or not the tweens should be forced to completion before being killed. | ||
| 427 | */ | ||
| 428 | public static function killTweensOf(target:Object, complete:Boolean=false):void { | ||
| 429 | if (target in _masterList) { | ||
| 430 | if (complete) { | ||
| 431 | var a:Array = _masterList[target]; | ||
| 432 | var i:int = a.length; | ||
| 433 | while (--i > -1) { | ||
| 434 | if (!TweenNano(a[i]).gc) { | ||
| 435 | TweenNano(a[i]).complete(false); | ||
| 436 | } | ||
| 437 | } | ||
| 438 | } | ||
| 439 | delete _masterList[target]; | ||
| 440 | } | ||
| 441 | } | ||
| 442 | |||
| 443 | /** @private **/ | ||
| 444 | private static function easeOut(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 445 | return -1 * (t /= d) * (t - 2); | ||
| 446 | } | ||
| 447 | |||
| 448 | } | ||
| 449 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | CHANGE LOG : GREENSOCK TWEENING PLATFORM | ||
| 2 | ---------------------------------------- | ||
| 3 | |||
| 4 | 2010-08-31 | ||
| 5 | ---------------------------------------------- | ||
| 6 | OverwriteManager 6.03 | ||
| 7 | - Worked around a bug in Flash that could (in EXTREMELY rare circumstances) cause an error in OverwriteManager. | ||
| 8 | |||
| 9 | 2010-05-25 | ||
| 10 | ---------------------------------------------- | ||
| 11 | TimelineLite 1.382 | ||
| 12 | TweenCore 1.382 | ||
| 13 | - Fixed issue that could cause an infinite loop if the only child of a TimelineLite/Max was removed and then added back to it and rendered. | ||
| 14 | |||
| 15 | 2010-05-24 | ||
| 16 | ---------------------------------------------- | ||
| 17 | TimelineLite 1.38 | ||
| 18 | SimpleTimeline 1.38 | ||
| 19 | TweenCore 1.38 | ||
| 20 | - Fixed issue that could prevent a tween from being removed properly from a completed TimelineLite/Max and, if inserted again and it's the only child of the TimelineLite/Max, it could cause an infinite loop when determining its totalDuration. | ||
| 21 | |||
| 22 | 2010-05-17 | ||
| 23 | ---------------------------------------------- | ||
| 24 | TimelineMax 11.381 | ||
| 25 | - TimelineMax.tweenTo() and TimelineMax.tweenFromTo() now automatically adjust the resulting tween's duration according to the TimelineMax's timeScale. | ||
| 26 | |||
| 27 | 2010-05-14 | ||
| 28 | ---------------------------------------------- | ||
| 29 | TweenMax 1.37 | ||
| 30 | TimelineMax 1.38 | ||
| 31 | - Fixed issue that caused the TweenMax or TimelineMax instance to render at its beginning state instead of its end state if the virutal playhead landed exactly on one of the times at which it repeats (like a tween/timeline with a duration of 1, repeated and rendered at a totalTime of exactly 2 would show as though it's at its beginning state). This only happened at precisely the repeat points. | ||
| 32 | |||
| 33 | 2010-05-11 (2) | ||
| 34 | ---------------------------------------------- | ||
| 35 | TimelineLite 1.371 | ||
| 36 | TimelineMax 1.371 | ||
| 37 | - Fixed issue where a TimelineLite/Max didn't recognize the need to continue running when a nested tween added more tweens via its onComplete. In other words, the TimelineLite/Max was on its final render but during the course of that render, more tweens were added, lengthening the timeline thus requiring it to continue running. | ||
| 38 | |||
| 39 | 2010-05-11 | ||
| 40 | ---------------------------------------------- | ||
| 41 | TimelineMax 1.37 | ||
| 42 | TweenNano 1.05 | ||
| 43 | - Fixed issue with a yoyo'd TimelineMax briefly rendering its end state on restart() | ||
| 44 | - Fixed default overwrite mode in TweenNano to be true (ALL_IMMEDIATE) instead of false (NONE). The documentation has always been correct, but the behavior wasn't (sorry!) | ||
| 45 | |||
| 46 | 2010-04-28 | ||
| 47 | ---------------------------------------------- | ||
| 48 | TweenCore 1.361 | ||
| 49 | TimelineMax 1.361 | ||
| 50 | - Fixed bug that prevented complete() from working properly when called on a TimelineLite or TimelineMax immediately after creating the instance | ||
| 51 | - Fixed TimelineMax.tweenTo() bug that prevented the tween from working properly when the destination time/label was the same as the current time/label. | ||
| 52 | |||
| 53 | 2010-04-27 | ||
| 54 | ---------------------------------------------- | ||
| 55 | TweenLite 11.36 | ||
| 56 | TweenMax 11.36 | ||
| 57 | TweenCore 1.36 | ||
| 58 | TimelineLite 1.36 | ||
| 59 | TimelineMax 1.36 | ||
| 60 | - Fixed compatibility with TweenLiteVars and TweenMaxVars (v11.35 introduced an incompatibility briefly) | ||
| 61 | |||
| 62 | |||
| 63 | 2010-04-21 | ||
| 64 | ---------------------------------------------- | ||
| 65 | TweenLite 11.35 | ||
| 66 | TweenMax 11.35 | ||
| 67 | TweenCore 1.35 | ||
| 68 | TimelineLite 1.35 | ||
| 69 | TimelineMax 1.35 | ||
| 70 | - There was a bug in the beta version of Adobe's AIR 2 for Andriod that caused TweenLite/Max/Nano not to work properly, so I implemented a workaround (the bug was NOT in TweenLite/Max/Nano). | ||
| 71 | - Added LinePath2D and RectanglePath2D motion paths and added the ability to autoRotate on CirclePath2D as well. CirclePath2DPlugin was updated as well. | ||
| 72 | |||
| 73 | |||
| 74 | 2010-04-10 | ||
| 75 | ---------------------------------------------- | ||
| 76 | TweenLite 11.32 | ||
| 77 | - Fixed bug that only appeared in the debug versions of the Flash Player which could cause an auto-overwritten tween not to be completely removed. | ||
| 78 | - Minor tweaks to enhance performance slightly. | ||
| 79 | |||
| 80 | |||
| 81 | 2010-03-31 | ||
| 82 | ---------------------------------------------- | ||
| 83 | OverwriteManager 6.01 | ||
| 84 | - Fixed a problem that could occur in very rare situations due to floating point math issues in Flash and could cause a tween not to be overwritten properly in AUTO mode. | ||
| 85 | |||
| 86 | |||
| 87 | 2010-03-28 | ||
| 88 | ---------------------------------------------- | ||
| 89 | TimelineLite 1.32 | ||
| 90 | TimelineMax 1.32 | ||
| 91 | - Fixed a bug introduced a little over 30 hours ago (v1.31) in TimelineLite and TimelineMax that prevented paused TimelineLites/Maxes from rendering (for example, if you paused it and tweened its currentTime property or used TimelineMax's tweenTo() method). | ||
| 92 | |||
| 93 | |||
| 94 | 2010-03-06 (2) | ||
| 95 | ---------------------------------------------- | ||
| 96 | TimelineLite 1.31 | ||
| 97 | TimelineMax 1.31 | ||
| 98 | - Updated the rendering routine in TimelineLite and TimelineMax so that if a child tween or callback pauses the timeline, it won't allow the rendering cycle to finish on that frame. | ||
| 99 | |||
| 100 | |||
| 101 | 2010-03-26 | ||
| 102 | ---------------------------------------------- | ||
| 103 | TweenLite 11.3 | ||
| 104 | TimelineLite 1.3 | ||
| 105 | MotionBlurPlugin 2.0 | ||
| 106 | AutoFitArea 1.4 | ||
| 107 | - Added 3rd parameter to TweenLite.killTweensOf() that allows you to define specific tweening properties to kill. This way you can kill only individual properties like "x" and "alpha" tweens of a particular object with TweenLite.killTweensOf(mc, false, {x:true, alpha:true}); | ||
| 108 | - Added 3rd parameter to TimelineLite's killTweensOf() to match the TweenLite.killTweensOf() addition. | ||
| 109 | - Rebuilt MotionBlurPlugin so that it accurately handles objects with DropShadowFilters or BevelFilters applied. | ||
| 110 | - Added "fastMode" special property to MotionBlurPlugin that can improve rendering speed by 500% or more. | ||
| 111 | - Added "padding" special property to MotionBlurPlugin to allow you to define how much space around the object to render with it in the captured BitmapData (to accommodate filters that extend beyond an object's edges like DropShadowFilter and GlowFilter). | ||
| 112 | - Added "calculateVisible" parameter to AutoFitArea.attach() to allow proper handling of objects that use masks internally. | ||
| 113 | |||
| 114 | |||
| 115 | 2010-03-06 | ||
| 116 | ---------------------------------------------- | ||
| 117 | TweenLite 11.2 | ||
| 118 | TweenMax 11.2 | ||
| 119 | TimelineLite 1.2 | ||
| 120 | TimelineMax 1.2 | ||
| 121 | - Added onInit and onInitParams special properties to TweenLite and TweenMax | ||
| 122 | - Added tweenFromTo() to TimelineMax | ||
| 123 | - Improved tweenTo() in TimelineMax so that it waits to determine its duration until the tween begins, making delayed tweens and sequenced ones more reliable. | ||
| 124 | - Fixed bug that could cause a TimelineLite's/Max's onComplete not to fire if a nested tween altered the TimelineLite's/Max's timeScale property on its very last render. | ||
| 125 | - Changed invalidate() so that it doesn't eliminate event listeners that were already added. (AS3 only) | ||
| 126 | - Added INIT event to the TweenEvent class (AS3 only) | ||
| 127 | - Updated ASDocs | ||
| 128 | |||
| 129 | |||
| 130 | 2010-03-01 | ||
| 131 | ---------------------------------------------- | ||
| 132 | TweenNano 1.02 | ||
| 133 | - Worked around Flash bug that caused the useFrames feature not to work properly in the AS2 flavor of TweenNano | ||
| 134 | |||
| 135 | |||
| 136 | 2010-02-01 | ||
| 137 | ---------------------------------------------- | ||
| 138 | TweenMax 11.14 | ||
| 139 | - Added updateTo() method to TweenMax that offers more useful and flexible functionality than setDestination() (which has been deprecated now in favor of updateTo()) | ||
| 140 | |||
| 141 | |||
| 142 | 1/19/2010, 4:30PM | ||
| 143 | ----------------- | ||
| 144 | RoughEase 0.6 | ||
| 145 | (beta versions of MotionPath classes) | ||
| 146 | - Added ability to taper the strength of RoughEase at the beginning or end | ||
| 147 | - Added ability to control whether or not the points on a RoughEase are randomized | ||
| 148 | - Added beta versions of MotionPath, Circle2D, PathFollower, Direction, and Circle2DPlugin classes. (note: API may change) | ||
| 149 | |||
| 150 | |||
| 151 | 1/18/2010, 9:30AM | ||
| 152 | ----------------- | ||
| 153 | TweenLite 1.133 | ||
| 154 | TweenMax 1.133 | ||
| 155 | TimelineLite 1.142 | ||
| 156 | SimpleTimeline 1.133 | ||
| 157 | - Fixed bug that could cause an endless loop in a very specific (extremely rare) scenario when a TweenCore is killed/disabled more than once and its parent timeline is at a particular spot in the linked list rendering order. | ||
| 158 | |||
| 159 | |||
| 160 | 1/15/2010, 11:00AM | ||
| 161 | ------------------ | ||
| 162 | TimelineLite 1.141 | ||
| 163 | - Fixed a bug that could prevent a TimelineLite/Max from being garbage collected in a very specific (rare) scenario. | ||
| 164 | |||
| 165 | |||
| 166 | 1/12/2010, 5:15PM | ||
| 167 | ----------------- | ||
| 168 | TimelineLite 1.14 | ||
| 169 | - Added removeLabel() to TimelineLite/Max | ||
| 170 | - Fixed bug in TransformMatrixPlugin that caused rotating objects to skew slightly in the middle of a tween (they always ended correctly, though) | ||
| 171 | - Updated documentation | ||
| 172 | |||
| 173 | |||
| 174 | 12/28/09, 9:30PM | ||
| 175 | ---------------- | ||
| 176 | TimelineMax 1.13 | ||
| 177 | - tweenTo() now respects a timeline's timeScale, adjusting the duration of the tween accordingly. | ||
| 178 | |||
| 179 | |||
| 180 | 12/19/09, 8:15PM | ||
| 181 | ----------------- | ||
| 182 | TweenLite 11.131 | ||
| 183 | TweenMax 11.131 | ||
| 184 | - Fixed minor bug that could cause a tween to report as active when it isn't. | ||
| 185 | - Added RoughEase | ||
| 186 | - Added RoughEase and SplitTextField to documentation | ||
| 187 | |||
| 188 | |||
| 189 | 12/8/09, 1PM | ||
| 190 | ---------------- | ||
| 191 | TweenLite 11.13 | ||
| 192 | TimelineLite 11.13 | ||
| 193 | TweenCore 1.13 | ||
| 194 | - Fixed bug that could prevent tweens from being properly removed from a TimelineLite/Max that has been completed | ||
| 195 | |||
| 196 | |||
| 197 | 11/25/09, 12:00PM | ||
| 198 | ------------------ | ||
| 199 | TweenLite 11.12 | ||
| 200 | TweenMax 11.12 | ||
| 201 | - Fixed problem that could cause a TweenLite.from() not to honor "paused:true" passed in through the constructor's vars object | ||
| 202 | - Fixed problem that could prevent killVars() from working on a rounded property in TweenMax | ||
| 203 | |||
| 204 | |||
| 205 | 11/21/09, 10:30AM | ||
| 206 | ----------------- | ||
| 207 | TimelineLite 1.12 | ||
| 208 | TimelineMax 1.12 | ||
| 209 | - Fixed issue that could cause a TimelineLite or TimelineMax not to honor a reverse() call or a call that altered the timeline's startTime when it happened inside a child tween/timeline on the very last render when the TimelineLite/Max would have normally completed. | ||
| 210 | |||
| 211 | |||
| 212 | 11/20/09, 11:00AM | ||
| 213 | ----------------- | ||
| 214 | TweenCore 1.11 | ||
| 215 | TweenMax 11.11 | ||
| 216 | - Fixed issue that caused onComplete not to fire on tweens that had yoyo set to true and an odd repeat value | ||
| 217 | |||
| 218 | |||
| 219 | 11/19/09, 10:00PM | ||
| 220 | ----------------- | ||
| 221 | TimelineLite 1.11 | ||
| 222 | TimelineMax 1.11 | ||
| 223 | SimpleTimeline 1.11 | ||
| 224 | - Fixed bug that could cause an unfinished tween to render once more after having been killed (and only in certain scenarios) | ||
| 225 | - Fixed bug with gotoAndPlay() sometimes inaccurately setting the currentTime | ||
| 226 | |||
| 227 | |||
| 228 | 11/12/09, 11:10PM | ||
| 229 | ----------------- | ||
| 230 | TimelineLite 1.1 | ||
| 231 | SimpleTimeline 1.1 | ||
| 232 | TweenCore 1.1 | ||
| 233 | - CRITICAL: Fixed bug that could cause an endless loop in very rare situations. It could also cause some odd behavior that would look like tweens/timelines got overwritten. | ||
| 234 | |||
| 235 | |||
| 236 | 11/7/09, 7:10AM | ||
| 237 | --------------- | ||
| 238 | SimpleTimeline 1.01 | ||
| 239 | TimelineLite 1.01 | ||
| 240 | TimelineMax 1.04 | ||
| 241 | TweenMax 1.104 | ||
| 242 | - Fixed bug that could cause odd overwriting behavior | ||
| 243 | - Worked around Flash bug that incorrectly reported modulus operations like 4 % 0.8 as 0.7999999999 instead of 0, causing occassional jumping/skipping in repeated/yoyo'd TweenMax or TimelineMax instances | ||
| 244 | |||
| 245 | |||
| 246 | 10/29/09, 11:30AM | ||
| 247 | ----------------- | ||
| 248 | TweenMax 11.103 | ||
| 249 | TimelineMax 1.03 | ||
| 250 | - Fixed bug that caused tweens/timelines with yoyo set to true and an odd number of repeats to end incorrectly | ||
| 251 | |||
| 252 | |||
| 253 | 10/27/09, 2:05PM | ||
| 254 | ---------------- | ||
| 255 | TweenMax 11.102 | ||
| 256 | - Fixed bug that could cause a repeated TweenMax not to fire an onComplete in certain scenarios. | ||
| 257 | |||
| 258 | |||
| 259 | 10/23/09, 3:00PM | ||
| 260 | ---------------- | ||
| 261 | TweenMax 11.101 | ||
| 262 | TimelineMax 1.01 | ||
| 263 | - Fixed minor bug in TimelineMax that could cause repeated instances to incorrectly report their currentTime after completing. | ||
| 264 | - Fixed bug in TweenMax.globalTimeScale that would only show up if you tried setting the property before creating any tweens. | ||
| 265 | |||
| 266 | |||
| 267 | 10/22/09, 11:50PM | ||
| 268 | ----------------- | ||
| 269 | TweenLite 11.101 | ||
| 270 | TweenMax 11.101 | ||
| 271 | TweenNano 1.01 | ||
| 272 | TweenPlugin 1.31 | ||
| 273 | - Very minor internal optimizations | ||
| 274 | - Added SoundTransformPlugin and EndVectorPlugin (AS3 only) | ||
| 275 | |||
| 276 | |||
| 277 | 10/21/09, 2PM CST | ||
| 278 | ----------------- | ||
| 279 | TweenLite 11.1 | ||
| 280 | TweenMax 11.1 | ||
| 281 | TimelineLite 1.0 | ||
| 282 | TimelineMax 1.0 | ||
| 283 | TweenNano 1.0 | ||
| 284 | TweenCore 1.0 | ||
| 285 | SimpleTimeline 1.0 | ||
| 286 | - Official first release of v11! | ||
| 287 | - Added repeat and repeatDelay getter/setter to TweenMax | ||
| 288 | |||
| 289 | |||
| 290 | 10/16/09, 1PM CST | ||
| 291 | ----------------- | ||
| 292 | TimelineLite 0.994 | ||
| 293 | - Added "offset" parameter to append() and appendMultiple() methods to allow you to offset the insertion point by a certain amount. | ||
| 294 | |||
| 295 | |||
| 296 | 10/13/09, 4:35PM CST | ||
| 297 | -------------------- | ||
| 298 | - Added new physics2D and physicsProps plugins for Club GreenSock members | ||
| 299 | |||
| 300 | |||
| 301 | 10/7/2009, 10:10PM CST | ||
| 302 | ---------------------- | ||
| 303 | TweenLite 11.099996 | ||
| 304 | TweenMax 11.099996 | ||
| 305 | TimelineLite 0.993 | ||
| 306 | TimelineMax 0.993 | ||
| 307 | TweenCore 0.993 | ||
| 308 | - Added onReverseComplete functionality in TweenLite | ||
| 309 | - Minor internal optimizations and restructuring | ||
| 310 | |||
| 311 | |||
| 312 | 10/4/09 12:00AM CST | ||
| 313 | ------------------- | ||
| 314 | TweenLite 11.099995 | ||
| 315 | TweenMax 11.099995 | ||
| 316 | TimelineLite 0.99 | ||
| 317 | TimelineMax 0.99 | ||
| 318 | TweenCore 0.99 | ||
| 319 | - Changed stop() to pause() in TweenCore (which affects TweenLite and TweenMax, but stop() was left in TimelineLite and TimelineMax in order to retain consistency with MovieClip.stop()) | ||
| 320 | - Changed TweenMax.stopAll() back to TweenMax.pauseAll() | ||
| 321 | - Removed TweenMax.killAllTweens() and TweenMax.killAllDelayedCalls() because the functionality is already present in TweenMax.killAll() | ||
| 322 | |||
| 323 | |||
| 324 | 10/2/09, 1:30PM CST | ||
| 325 | ------------------- | ||
| 326 | TweenLite 11.099994 | ||
| 327 | TweenMax 11.099994 | ||
| 328 | TimelineLite 0.97 | ||
| 329 | TimelineMax 0.97 | ||
| 330 | OverwriteManager 6.0 | ||
| 331 | - Added stop(), play(), resume(), restart(), reverse(), methods and paused, reversed, and totalTime properties to TweenLite | ||
| 332 | - Updated documentation | ||
| 333 | - Added new PREEXISTING mode to OverwriteManager | ||
| 334 | - Made TweenLite and TweenMax re-parse the "ease" property of the vars object after a tween has been invalidated (invalidate()) | ||
| 335 | - Minor speed enhancements to a few plugins | ||
| 336 | |||
| 337 | |||
| 338 | 9/27/09, 11:35PM CST | ||
| 339 | -------------------- | ||
| 340 | TimelineLite 0.96 | ||
| 341 | TimelineMax 0.96 | ||
| 342 | - If the label isn't found in TimelineLite.getLabelTime(), it will now return -1 instead of 0 which helps determine if a label exists. | ||
| 343 | - Now TimelineMax.tweenTo() won't do anything if you pass in a non-existent label. (previously it would default to a time of 0) | ||
| 344 | |||
| 345 | |||
| 346 | 9/24/09, 1:20PM CST | ||
| 347 | ------------------- | ||
| 348 | TweenMax 11.099993 | ||
| 349 | - Fixed bug that caused roundProps not to function properly on the first property. | ||
| 350 | |||
| 351 | |||
| 352 | 9/23/09, 2PM CST | ||
| 353 | ---------------- | ||
| 354 | OverwriteManager 5.42 | ||
| 355 | TweenLite 11.099993 | ||
| 356 | - Fixed bug in AUTO overwriting mode that could cause tweens to be overwritten when they shouldn't in certain situations. | ||
| 357 | |||
| 358 | |||
| 359 | 9/22/09, 3:15PM CST | ||
| 360 | ------------------- | ||
| 361 | TweenLite 11.099992 | ||
| 362 | TweenMax 11.099992 | ||
| 363 | TimelineLite 0.95 | ||
| 364 | TimelineMax 0.95 | ||
| 365 | - Fixed bug that could cause onStart to fire twice if immediateRender was set to true | ||
| 366 | |||
| 367 | |||
| 368 | 9/22/09, 12PM CST | ||
| 369 | ----------------- | ||
| 370 | - Fixed bug in MotionBlurPlugin | ||
| 371 | |||
| 372 | |||
| 373 | 9/15/09, 1:15PM CST | ||
| 374 | ------------------- | ||
| 375 | TweenLite 11.099991 | ||
| 376 | TweenMax 11.099991 | ||
| 377 | OverwriteManager 5.4 | ||
| 378 | TimelineMax 0.941 | ||
| 379 | TweenPlugin 1.3 | ||
| 380 | - Altered AUTO overwriting code so that if all of a tween's tweening properties have been overwritten, the entire tween is killed (previously, the tween could live and its onComplete/onUpdate would still fire) | ||
| 381 | - Fixed bug in AS3 version of TimelineMax's getLabelBefore(), getLabelAfter(), and currentLabel | ||
| 382 | |||
| 383 | |||
| 384 | 9/12/09, 5PM CST | ||
| 385 | ----------------- | ||
| 386 | TweenLite 11.09999 | ||
| 387 | TweenMax 11.09999 | ||
| 388 | TimelineLite 0.94 | ||
| 389 | TimelineMax 0.94 | ||
| 390 | OverwriteManager 5.3 | ||
| 391 | - Changed "time" property to "currentTime". | ||
| 392 | - Changed "progress" property to "currentProgress". | ||
| 393 | - Added tweenTo() method to TimelineMax. | ||
| 394 | - Fixed bug that could cause a motionBlur not to render correctly if an alpha tween overwrote it. | ||
| 395 | - Fixed minor bugs in the AS2 version of several plugins. | ||
| 396 | |||
| 397 | |||
| 398 | 9/10/09, 1PM CST | ||
| 399 | ---------------- | ||
| 400 | TweenLite 11.09998 | ||
| 401 | - Fixed overwriting bug | ||
| 402 | |||
| 403 | |||
| 404 | 9/9/09, 6PM CST | ||
| 405 | ------------------ | ||
| 406 | TimelineLite 0.93 | ||
| 407 | TimelineMax 0.93 | ||
| 408 | TweenLite 11.09997 | ||
| 409 | TweenMax 11.09997 | ||
| 410 | - Added getLabelTime() to TimelineLite | ||
| 411 | - Added currentTime and getLabelBefore() and getLabelAfter() to TimelineMax | ||
| 412 | - Added new "ratio" property in TweenLite/Max/Nano | ||
| 413 | |||
| 414 | |||
| 415 | 9/6/2009, 2:10AM CST | ||
| 416 | -------------------- | ||
| 417 | TweenLite 11.09995 | ||
| 418 | TweenMax 11.09995 | ||
| 419 | TimelineLite 0.92 | ||
| 420 | TimelineMax 0.92 | ||
| 421 | TweenNano 0.92 | ||
| 422 | - Minor speed enhancements and internal modifications | ||
| 423 | - Added ability to activate certain easing classes in TweenMax so that they use optimized internal code to speed things up. | ||
| 424 | Classes include Strong, Quint, Quad, Cubic, Linear, and Quart | ||
| 425 | |||
| 426 | |||
| 427 | 8/22/2009, 2:30AM CST | ||
| 428 | --------------------- | ||
| 429 | TimelineLite 0.91 | ||
| 430 | TransformMatrixPlugin 0.95 | ||
| 431 | - Fixed bug that caused odd behavior when using insertMultiple() with tweens that had a timeScale other than 1. | ||
| 432 | - Changed the behavior of transformMatrix plugin to more closely match the Flash IDE's way of skewing | ||
| 433 | - Altered the filter plugins so that you can use a regular BitmapFilter object (like GlowFilter, BlurFilter, etc.) to define vars in tweens. | ||
| 434 | |||
| 435 | |||
| 436 | 8/17/2009, 11:15AM CST | ||
| 437 | ---------------------- | ||
| 438 | TimelineLite 0.9 | ||
| 439 | TweenMax 11.09994 | ||
| 440 | DynamicPropsPlugin, AutoAlphaPlugin, and MotionBlurPlugin were updated too | ||
| 441 | - Added appendMultiple() and prependMultiple() to TimelineLite/Max | ||
| 442 | - Added shiftChildren() to TimelineLite/Max | ||
| 443 | - Fixed bug in TweenMax.killChildTweensOf() | ||
| 444 | - Added the ability to pass parameters to dynamicProps functions | ||
| 445 | - Removed trace() from MotionBlurPlugin | ||
| 446 | |||
| 447 | |||
| 448 | 7/18/2009, 7:30PM CST | ||
| 449 | --------------------- | ||
| 450 | TweenLite 11.09993 | ||
| 451 | TweenMax 11.09993 | ||
| 452 | TimelineLite 0.88 | ||
| 453 | TimelineMax 0.88 | ||
| 454 | SimpleTimeline 0.88 | ||
| 455 | TweenCore 0.88 | ||
| 456 | - Added invalidate() method to TweenCore (which means it's available in TweenLite, TweenMax, TimelineLite, and TimelineMax) | ||
| 457 | - Fixed bug that could cause the player to crash if a TweenCore was added to a timeline after the timeline had completed and was then reversed. | ||
| 458 | - Fixed bug in AS2 version of TweenMax.setDestination() | ||
| 459 | |||
| 460 | |||
| 461 | 7/16/2009, 9AM CST | ||
| 462 | ------------------ | ||
| 463 | OverwriteManager 5.1 | ||
| 464 | - Added ALL_AFTER mode to OverwriteManager | ||
| 465 | - Fixed bug in OverwriteManager that was introduced in 5.06 | ||
| 466 | |||
| 467 | |||
| 468 | 7/15/2009, 2:30PM CST | ||
| 469 | --------------------- | ||
| 470 | TimelineLite 0.87 | ||
| 471 | TimelineMax 0.87 | ||
| 472 | - Removed shorthand syntax in TimelineLite/Max in order to prevent confusion ("why won't insert()/append()/prepend() | ||
| 473 | accommodate the shorthand syntax?") and reduce the file size. This also means that there's no need for the tweenClass | ||
| 474 | special parameter. | ||
| 475 | - Fixed minor ASDoc formatting problems. | ||
| 476 | |||
| 477 | |||
| 478 | 7/15/2009, 1:45AM CST | ||
| 479 | --------------------- | ||
| 480 | TweenLite 11.09992 | ||
| 481 | TweenMax 11.09992 | ||
| 482 | TimelineLite 0.86 | ||
| 483 | TimelineMax 0.86 | ||
| 484 | TweenNano 0.86 | ||
| 485 | - IMPORTANT: Changed base package name from "gs" to "com.greensock" in order to comply with industry standards. I realize this may cause some problems | ||
| 486 | with existing code, but with all the enhancements and changes in v11, now seemed like the best time to make the change. Sorry for any inconvenience! | ||
| 487 | - Fixed some documentation | ||
| 488 | |||
| 489 | 7/13/2009, 4:45PM CST | ||
| 490 | --------------------- | ||
| 491 | TweenMax 11.09991 | ||
| 492 | - Fixed bug in allTo() and allFrom() and allFromTo() that was introduced last version (when removing the "$" signs). | ||
| 493 | |||
| 494 | |||
| 495 | 7/10/2009, 2PM CST | ||
| 496 | ------------------ | ||
| 497 | TweenLite 11.0999 | ||
| 498 | TweenMax 11.0999 | ||
| 499 | TimelineLite 0.85 | ||
| 500 | TweenCore 0.85 | ||
| 501 | - Fixed bug that could cause a TimelineLite/Max to inaccurately report its duration after changing the startTime of one of its children | ||
| 502 | - Fixed bug in CustomEase and EaseLookup that was introduced 24 hours ago. | ||
| 503 | |||
| 504 | |||
| 505 | 7/9/2009, 3PM CST | ||
| 506 | ----------------- | ||
| 507 | TweenLite 11.0997 | ||
| 508 | TweenMax 11.0997 | ||
| 509 | OverwriteManager 5.05 | ||
| 510 | TimelineLite 0.83 | ||
| 511 | TimelineMax 0.83 | ||
| 512 | TweenNano 0.84 | ||
| 513 | SimpleTimeline 0.83 | ||
| 514 | Tweenable 0.84 | ||
| 515 | - Fixed bug in timeline classes that prevented getChildren() from returning nested tweens/timelines properly | ||
| 516 | - Fixed bug in timeline classes and TweenMaxthat could cause a delay if a nested timeline was paused at exactly zero seconds and then resumed later. | ||
| 517 | - Fixed bug in OverwriteManager that could overwrite tweens in paused timelines. | ||
| 518 | - Changed the name of the super-lightweight new class from "TweenLt" to "TweenNano". | ||
| 519 | - Changed the package for the core tweening classes from gs.core.tween to simply gs.core | ||
| 520 | - Changed the package for the vars classes (TweenLiteVars, TweenMaxVars, etc.) from gs.utils.tween to gs.data | ||
| 521 | - Removed "$" from all parameters | ||
| 522 | |||
| 523 | |||
| 524 | 7/1/2009, 1PM CST | ||
| 525 | ----------------- | ||
| 526 | TweenLite 11.0996 | ||
| 527 | TweenMax 11.0996 | ||
| 528 | TweenLt 0.83 | ||
| 529 | Tweenable 0.83 | ||
| 530 | - Removed TweenLite.removeTween() and TweenMax.removeTween() in favor of a common kill() method. So what used to be TweenLite.removeTween(myTween) is now simply myTween.kill(); | ||
| 531 | - Added kill() to all tweenables including TimelineLite and TimelineMax. | ||
| 532 | |||
| 533 | |||
| 534 | 6/29/09, 4:30PM CST | ||
| 535 | ------------------- | ||
| 536 | TweenMax 11.0995 | ||
| 537 | TimelineLite 0.82 | ||
| 538 | TimelineMax 0.82 | ||
| 539 | - Fixed bug that could cause tweens to be rendered incorrectly in a TimelineMax that was repeated and restarted (in rare circumstances) | ||
| 540 | - Fixed bug in TweenMax that could render a tween incorrectly if the "time" property is set during a yoyo phase. | ||
| 541 | |||
| 542 | |||
| 543 | 6/22/09, 2:45PM CST | ||
| 544 | ------------------- | ||
| 545 | TweenMax 11.0994 | ||
| 546 | TimelineMax 0.81 | ||
| 547 | - Fixed bug in TweenMax.from() that could cause it to incorrectly render the first frame. | ||
| 548 | |||
| 549 | |||
| 550 | 6/16/09, 9:30AM CST | ||
| 551 | ---------------- | ||
| 552 | TweenLite 11.0991 | ||
| 553 | TweenMax 11.0993 | ||
| 554 | TimelineLite 0.8 | ||
| 555 | TimelineMax 0.8 | ||
| 556 | Tweenable 0.8 | ||
| 557 | TweenLt 0.8 | ||
| 558 | - Added new TweenLt class that is a super-lightweight (1.6k) version of TweenLite without plugin capability, OverwriteManager integration, and a few other features. TweenLt is not recommended unless you absolutely cannot afford the extra 2.4k that the regular TweenLite class would cost. | ||
| 559 | - Prevented timelines from rendering times less than zero or greater than the totalDuration. | ||
| 560 | - Fixed very minor bug in TweenMax.isTweening() | ||
| 561 | - Moved the ALIGN constants into their own TweenAlign class. (TweenAlign.START, TweenAlign.NORMAL, and TweenAlign.SEQUENCE) | ||
| 562 | - Optimized some minor code in the easing equations. | ||
| 563 | - Prevented TimelineLite/Max instances from having children with negative startTimes (they'll automatically move all children if a negative startTime is encountered so that the first child starts at zero) | ||
| 564 | |||
| 565 | |||
| 566 | 6/3/2009, 6PM CST | ||
| 567 | ----------------- | ||
| 568 | TweenMax 11.0991 | ||
| 569 | - Fixed bug that could cause a TweenMax not to be able to restart after it completes. | ||
| 570 | |||
| 571 | |||
| 572 | 6/1/2009, 5:20PM CST | ||
| 573 | -------------------- | ||
| 574 | TimelineLite 0.7 | ||
| 575 | TimelineMax 0.7 | ||
| 576 | TweenLite 11.099 | ||
| 577 | TweenMax 11.099 | ||
| 578 | Tweenable 0.7 | ||
| 579 | SimpleTimeline 0.7 | ||
| 580 | - Fixed bug that caused onStart to only fire the first time through a tween/timeline | ||
| 581 | - Fixed issue that could cause a zero-duration tween/timeline to not render correctly if its parent timeline was rendered at a time that preceded the start time of the zero-duration tween/timeline | ||
| 582 | |||
| 583 | |||
| 584 | 5/27/2009, 11:20AM CST | ||
| 585 | ---------------------- | ||
| 586 | TimelineLite 0.69 | ||
| 587 | - Fixed bug that could cause timelines to get ignored in the rendering queue if they were created with zero tweens, immediately paused, and then populated, and subsequently unpaused. | ||
| 588 | |||
| 589 | |||
| 590 | 5/26/2009, 10:45PM CST | ||
| 591 | ---------------------- | ||
| 592 | TimelineLite 0.68 | ||
| 593 | TimelineMax 0.68 | ||
| 594 | - Fixed bug in rendering a reversed timeline where some tweens or nested timelines could be skipped | ||
| 595 | |||
| 596 | |||
| 597 | 5/23/09, 11:45PM CST | ||
| 598 | -------------------- | ||
| 599 | TweenLite 11.0988 | ||
| 600 | - Fixed bug in TweenLite that could cause immediate renders to be skipped. | ||
| 601 | |||
| 602 | |||
| 603 | 5/23/09, 2:00PM CST | ||
| 604 | ------------------- | ||
| 605 | TweenLite 11.0987 | ||
| 606 | TweenMax 11.0987 | ||
| 607 | TimelineLite 0.67 | ||
| 608 | TimelineMax 0.67 | ||
| 609 | - Added "suppressEvent" capabilities throughout the classes. This is particularly useful in the timeline gotoAndStop(), gotoAndPlay(), goto(), and restart() methods because you can skip to a different time/position without having any onUpdate, onComplete, onReverseComplete, etc. callbacks or events triggered. | ||
| 610 | - Added logic that allows the "immediateRender" special property to be honored if it is passed in through the "from" vars in TweenMax.allFromTo() and TweenMax.fromTo(). (previously it was only honored if it was passed through the "to" vars object) | ||
| 611 | - Fixed bug that could cause tweens inside nested timelines that start at exactly zero seconds to render incorrectly | ||
| 612 | |||
| 613 | |||
| 614 | 5/22/09, 9:30AM CST | ||
| 615 | ------------------- | ||
| 616 | TimelineLite 0.66 | ||
| 617 | TimelineMax 0.66 | ||
| 618 | - Fixed bug that could cause tweens to be skipped in the rendering queue when their start and end times were between the last render and the current one. | ||
| 619 | |||
| 620 | |||
| 621 | 5/12/2009, 11:55PM CST | ||
| 622 | ---------------------- | ||
| 623 | TweenMax 11.0985 | ||
| 624 | TimelineLite 0.65 | ||
| 625 | TimelineMax 0.65 | ||
| 626 | SimpleTimeline 0.63 | ||
| 627 | - Now if a TimelineLite or TimelineMax contains a paused child tween/timeline, it will not complete (calling an onComplete or firing a COMPLETE event) until the child is unpaused. | ||
| 628 | - Fixed bug in TweenMax.pauseAll() | ||
| 629 | - Fixed bug that could cause odd behavior if certain actions were performed on a TimelineLite/Max when it was paused | ||
| 630 | - Fixed bug in MotionBlurPlugin that prevented it from rendering properly initially if the tween was restarted or set back to a progress of zero. | ||
| 631 | |||
| 632 | |||
| 633 | 5/8/2009, 2:05PM CST | ||
| 634 | -------------------- | ||
| 635 | TimelineLite 0.64 | ||
| 636 | TimelineMax 0.64 | ||
| 637 | SimpleTimeline 0.62 | ||
| 638 | - Fixed bug that could cause an infinite loop under very specific circumstances | ||
| 639 | |||
| 640 | |||
| 641 | 5/6/2009, 7PM CST | ||
| 642 | ----------------- | ||
| 643 | TweenLite 11.0984 | ||
| 644 | TweenMax 11.0984 | ||
| 645 | TimelineLite 0.63 | ||
| 646 | TimelineMax 0.63 | ||
| 647 | - Added ScrollRectPlugin | ||
| 648 | - Added a list of all plugins to the top of TweenLite and TweenMax to make it easy to activate/deactivate them. | ||
| 649 | - Fixed bug in TweenMax's timeScale and globalTimeScale properties | ||
| 650 | - Improved performance in timeline classes slightly | ||
| 651 | - Fixed minor bug in MotionBlurPlugin | ||
| 652 | - Minor bug fixes | ||
| 653 | |||
| 654 | |||
| 655 | 5/4/2009, 9:30PM CST | ||
| 656 | -------------------- | ||
| 657 | TweenLite 11.0982 | ||
| 658 | TweenMax 11.0983 | ||
| 659 | TimelineLite 0.62 | ||
| 660 | TimelineMax 0.62 | ||
| 661 | - Minor performance improvements | ||
| 662 | |||
| 663 | |||
| 664 | 5/4/2009, 5PM CST | ||
| 665 | ----------------- | ||
| 666 | TweenMax 11.0982 | ||
| 667 | TimelineLite 0.61 | ||
| 668 | TimelineMax 0.61 | ||
| 669 | - Added onRepeat, onRepeatParams, onReverseComplete, and onReverseCompleteParams special properties to TweenMax and TimelineMax | ||
| 670 | - Added onReverseComplete and onReverseCompleteParams to TimelineLite | ||
| 671 | - Added onStart callback functionality to TimelineMax | ||
| 672 | - Eliminated code that maintained backwards compatibility with the old "loop" and "yoyo" special properties in TweenMax. It seemed like it would cause more confusion than help. | ||
| 673 | - Fixed bug that could cause a TweenMax/TimelineLite/Max to incorrectly report its "progress" property immediately after being reversed | ||
| 674 | - Fixed bug that could cause a TweenMax/TimelineLite/Max to render incorrectly when its progress/totalProgress/time/totalTime property was set immediately after being reversed | ||
| 675 | |||
| 676 | |||
| 677 | |||
| 678 | 5/1/2009, 11:15PM CST | ||
| 679 | --------------------- | ||
| 680 | TweenLite 11.0981 | ||
| 681 | TweenMax 11.0981 | ||
| 682 | TimelineLite 0.6 | ||
| 683 | TimelineMax 0.6 | ||
| 684 | SimpleTimeline 0.6 | ||
| 685 | Tweenable 0.6 | ||
| 686 | - **IMPORTANT** By default, NO plugins are activated in TweenLite. Previously 7 plugins were activated by default in order to maintain backwards compatibility. However, after asking the community for input, the VAST majority strongly recommended removing the activation code from inside TweenLite to minimize the file size. TweenMax still has the same plugins activated that it always had. | ||
| 687 | - Changed the way reversing affects time/totalTime/progress/totalProgress so that they always reflect the tween's/timeline's forward position regardless of reversing. | ||
| 688 | - renderTime() renders consistently (according to a tween's/timeline's forward orientation) now regardless of the tween's/timeline's reversed state. | ||
| 689 | |||
| 690 | |||
| 691 | 4/30/2009, 12:09PM CST | ||
| 692 | ---------------------- | ||
| 693 | TimelineLite 0.561 | ||
| 694 | TimelineMax 0.54 | ||
| 695 | - Fixed a bug in goto() that could render things incorrectly when a timeline is reversed. | ||
| 696 | |||
| 697 | |||
| 698 | 4/30/2009, 12:05AM CST | ||
| 699 | --------------------- | ||
| 700 | TweenMax 11.098 | ||
| 701 | TimelineLite 0.56 | ||
| 702 | - **IMPORTANT** Changed reverse() and play() behavior so that play() ALWAYS forces the TweenMax/TimelineLite/TimelineMax instance to play forwards and reverse() ALWAYS forces it to play backwards. Previously, reverse() would flip directions, so if it was currently running backwards, reverse() would cause it to go forwards, etc. It proved to be confusing to end users, so I switched to the new behavior. | ||
| 703 | - **IMPORTANT** The "reversed" setter in TweenMax/TimelineLite/TimelineMax does NOT automatically force the tween/timeline to resume. Previously it did. | ||
| 704 | - Added resume() method to TweenMax/TimelineLite/TimelineMax which is similar to play() except it won't alter the direction of a tween (if it is reversed, it will stay reversed after calling resume()). | ||
| 705 | - Added fromTo() and allFromTo() to TweenMax. | ||
| 706 | - Added stop() to TweenMax to be consistent with the timeline classes | ||
| 707 | |||
| 708 | |||
| 709 | 4/28/2009, 12:35AM CST | ||
| 710 | ---------------------- | ||
| 711 | TweenMax 11.0971 | ||
| 712 | TimelineLite 0.55 | ||
| 713 | OverwriteManager 5.01 | ||
| 714 | - Fixed bug that could cause a TimelineMax repeat to render incorrectly because tweens could get overwritten | ||
| 715 | - Added the ability to set the "reversed" property via the constructor's vars object in TweenMax, TimelineLite, and TimelineMax. | ||
| 716 | |||
| 717 | |||
| 718 | 4/27/2009, 1PM CST | ||
| 719 | ------------------ | ||
| 720 | TimelineLite 0.54 | ||
| 721 | - Fixed bug that could cause a TimelineMax repeat to render incorrectly | ||
| 722 | |||
| 723 | |||
| 724 | 4/24/2009, 1:30AM CST | ||
| 725 | --------------------- | ||
| 726 | TweenMax 11.097 | ||
| 727 | TweenLite 11.097 | ||
| 728 | TimelineLite 0.53 | ||
| 729 | TimelineMax 0.53 | ||
| 730 | - Minor changes that would prevent potential missed rendering of tweens/timelines that complete and then are re-enabled later | ||
| 731 | - Added TweenEvent.REPEAT Event dispatching in TweenMax | ||
| 732 | - Changed the way TweenLite/Max communicate with TweenPlugins (so the plugins can optionally sense when a tween gets disabled or when the plugin PropTween gets overwritten/removed) which was necessary for MotionBlurPlugin to handle overwriting properly. | ||
| 733 | - Removed "renderOnStart" special property functionality, and replaced it with "immediateRender" which provides more flexibility. | ||
| 734 | - Reduced size of TweenPlugin slightly | ||
| 735 | - Minor optimizations | ||
| 736 | - Fixed MotionBlurPlugin overwrite bug | ||
| 737 | - Fixed MotionBlurPlugin bug that prevented blurring when a tween was reversed or yoyo'd | ||
| 738 |
| 1 | /** | ||
| 2 | * VERSION: 2.1 | ||
| 3 | * DATE: 2009-09-12 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.core { | ||
| 8 | /** | ||
| 9 | * Stores information about an individual property tween. There is no reason to use this class directly - TweenLite, TweenMax, and some plugins use it internally.<br /><br /> | ||
| 10 | * | ||
| 11 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 12 | * | ||
| 13 | * @author Jack Doyle, jack@greensock.com | ||
| 14 | */ | ||
| 15 | public class PropTween { | ||
| 16 | /** Target object **/ | ||
| 17 | public var target:Object; | ||
| 18 | /** Name of the property that is being tweened **/ | ||
| 19 | public var property:String; | ||
| 20 | /** Starting value **/ | ||
| 21 | public var start:Number; | ||
| 22 | /** Amount to change (basically, the difference between the starting value and ending value) **/ | ||
| 23 | public var change:Number; | ||
| 24 | /** Alias to associate with the PropTween which is typically the same as the property, but can be different, particularly for plugins. **/ | ||
| 25 | public var name:String; | ||
| 26 | /** Priority in the rendering queue. The lower the value the later it will be tweened. Typically all PropTweens get a priority of 0, but some plugins must be rendered later (or earlier) **/ | ||
| 27 | public var priority:int; | ||
| 28 | /** If the target of the PropTween is a TweenPlugin, isPlugin should be true. **/ | ||
| 29 | public var isPlugin:Boolean; | ||
| 30 | /** Next PropTween in the linked list **/ | ||
| 31 | public var nextNode:PropTween; | ||
| 32 | /** Previous PropTween in the linked list **/ | ||
| 33 | public var prevNode:PropTween; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Constructor | ||
| 37 | * | ||
| 38 | * @param target Target object | ||
| 39 | * @param property Name of the property that is being tweened | ||
| 40 | * @param start Starting value | ||
| 41 | * @param change Amount to change (basically, the difference between the starting value and ending value) | ||
| 42 | * @param name Alias to associate with the PropTween which is typically the same as the property, but can be different, particularly for plugins. | ||
| 43 | * @param isPlugin If the target of the PropTween is a TweenPlugin, isPlugin should be true. | ||
| 44 | * @param nextNode Next PropTween in the linked list | ||
| 45 | * @param priority Priority in the rendering queue. The lower the value the later it will be tweened. Typically all PropTweens get a priority of 0, but some plugins must be rendered later (or earlier) | ||
| 46 | */ | ||
| 47 | public function PropTween(target:Object, property:String, start:Number, change:Number, name:String, isPlugin:Boolean, nextNode:PropTween=null, priority:int=0) { | ||
| 48 | this.target = target; | ||
| 49 | this.property = property; | ||
| 50 | this.start = start; | ||
| 51 | this.change = change; | ||
| 52 | this.name = name; | ||
| 53 | this.isPlugin = isPlugin; | ||
| 54 | if (nextNode) { | ||
| 55 | nextNode.prevNode = this; | ||
| 56 | this.nextNode = nextNode; | ||
| 57 | } | ||
| 58 | this.priority = priority; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.38 | ||
| 3 | * DATE: 2010-05-24 | ||
| 4 | * AS3 (AS2 version is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.core { | ||
| 8 | /** | ||
| 9 | * SimpleTimeline is the base class for the TimelineLite and TimelineMax classes. It provides the | ||
| 10 | * most basic timeline functionality and is used for the root timelines in TweenLite. It is meant | ||
| 11 | * to be very fast and lightweight. <br /><br /> | ||
| 12 | * | ||
| 13 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 14 | * | ||
| 15 | * @author Jack Doyle, jack@greensock.com | ||
| 16 | */ | ||
| 17 | public class SimpleTimeline extends TweenCore { | ||
| 18 | /** @private **/ | ||
| 19 | protected var _firstChild:TweenCore; | ||
| 20 | /** @private **/ | ||
| 21 | protected var _lastChild:TweenCore; | ||
| 22 | /** If a timeline's autoRemoveChildren is true, its children will be removed and made eligible for garbage collection as soon as they complete. This is the default behavior for the main/root timeline. **/ | ||
| 23 | public var autoRemoveChildren:Boolean; | ||
| 24 | |||
| 25 | public function SimpleTimeline(vars:Object=null) { | ||
| 26 | super(0, vars); | ||
| 27 | } | ||
| 28 | |||
| 29 | /** @private **/ | ||
| 30 | public function addChild(tween:TweenCore):void { | ||
| 31 | if (!tween.cachedOrphan && tween.timeline) { | ||
| 32 | tween.timeline.remove(tween, true); //removes from existing timeline so that it can be properly added to this one. | ||
| 33 | } | ||
| 34 | tween.timeline = this; | ||
| 35 | if (tween.gc) { | ||
| 36 | tween.setEnabled(true, true); | ||
| 37 | } | ||
| 38 | if (_firstChild) { | ||
| 39 | _firstChild.prevNode = tween; | ||
| 40 | } | ||
| 41 | tween.nextNode = _firstChild; | ||
| 42 | _firstChild = tween; | ||
| 43 | tween.prevNode = null; | ||
| 44 | tween.cachedOrphan = false; | ||
| 45 | } | ||
| 46 | |||
| 47 | /** @private **/ | ||
| 48 | public function remove(tween:TweenCore, skipDisable:Boolean=false):void { | ||
| 49 | if (tween.cachedOrphan) { | ||
| 50 | return; //already removed! | ||
| 51 | } else if (!skipDisable) { | ||
| 52 | tween.setEnabled(false, true); | ||
| 53 | } | ||
| 54 | |||
| 55 | if (tween.nextNode) { | ||
| 56 | tween.nextNode.prevNode = tween.prevNode; | ||
| 57 | } else if (_lastChild == tween) { | ||
| 58 | _lastChild = tween.prevNode; | ||
| 59 | } | ||
| 60 | if (tween.prevNode) { | ||
| 61 | tween.prevNode.nextNode = tween.nextNode; | ||
| 62 | } else if (_firstChild == tween) { | ||
| 63 | _firstChild = tween.nextNode; | ||
| 64 | } | ||
| 65 | tween.cachedOrphan = true; | ||
| 66 | //don't null nextNode and prevNode, otherwise the chain could break in rendering loops. | ||
| 67 | } | ||
| 68 | |||
| 69 | /** @private **/ | ||
| 70 | override public function renderTime(time:Number, suppressEvents:Boolean=false, force:Boolean=false):void { | ||
| 71 | var tween:TweenCore = _firstChild, dur:Number, next:TweenCore; | ||
| 72 | this.cachedTotalTime = time; | ||
| 73 | this.cachedTime = time; | ||
| 74 | |||
| 75 | while (tween) { | ||
| 76 | next = tween.nextNode; //record it here because the value could change after rendering... | ||
| 77 | if (tween.active || (time >= tween.cachedStartTime && !tween.cachedPaused && !tween.gc)) { | ||
| 78 | if (!tween.cachedReversed) { | ||
| 79 | tween.renderTime((time - tween.cachedStartTime) * tween.cachedTimeScale, suppressEvents, false); | ||
| 80 | } else { | ||
| 81 | dur = (tween.cacheIsDirty) ? tween.totalDuration : tween.cachedTotalDuration; | ||
| 82 | tween.renderTime(dur - ((time - tween.cachedStartTime) * tween.cachedTimeScale), suppressEvents, false); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | tween = next; | ||
| 86 | } | ||
| 87 | |||
| 88 | } | ||
| 89 | |||
| 90 | //---- GETTERS / SETTERS ------------------------------------------------------------------------------ | ||
| 91 | |||
| 92 | /** | ||
| 93 | * @private | ||
| 94 | * Reports the totalTime of the timeline without capping the number at the totalDuration (max) and zero (minimum) which can be useful when | ||
| 95 | * unpausing tweens/timelines. Imagine a case where a paused tween is in a timeline that has already reached the end, but then | ||
| 96 | * the tween gets unpaused - it needs a way to place itself accurately in time AFTER what was previously the timeline's end time. | ||
| 97 | * In a SimpleTimeline, rawTime is always the same as cachedTotalTime, but in TimelineLite and TimelineMax, it can be different. | ||
| 98 | * | ||
| 99 | * @return The totalTime of the timeline without capping the number at the totalDuration (max) and zero (minimum) | ||
| 100 | */ | ||
| 101 | public function get rawTime():Number { | ||
| 102 | return this.cachedTotalTime; | ||
| 103 | } | ||
| 104 | |||
| 105 | } | ||
| 106 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.382 | ||
| 3 | * DATE: 2010-05-25 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | |||
| 8 | package com.greensock.core { | ||
| 9 | import com.greensock.*; | ||
| 10 | /** | ||
| 11 | * TweenCore is the base class for all TweenLite, TweenMax, TimelineLite, and TimelineMax classes and | ||
| 12 | * provides core functionality and properties. There is no reason to use this class directly.<br /><br /> | ||
| 13 | * | ||
| 14 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 15 | * | ||
| 16 | * @author Jack Doyle, jack@greensock.com | ||
| 17 | */ | ||
| 18 | public class TweenCore { | ||
| 19 | /** @private **/ | ||
| 20 | public static const version:Number = 1.382; | ||
| 21 | |||
| 22 | /** @private **/ | ||
| 23 | protected static var _classInitted:Boolean; | ||
| 24 | |||
| 25 | /** @private Delay in seconds (or frames for frames-based tweens/timelines) **/ | ||
| 26 | protected var _delay:Number; | ||
| 27 | /** @private Has onUpdate. Tracking this as a Boolean value is faster than checking this.vars.onUpdate != null. **/ | ||
| 28 | protected var _hasUpdate:Boolean; | ||
| 29 | /** @private Primarily used for zero-duration tweens to determine the direction/momentum of time which controls whether the starting or ending values should be rendered. For example, if a zero-duration tween renders and then its timeline reverses and goes back before the startTime, the zero-duration tween must render the starting values. Otherwise, if the render time is zero or later, it should always render the ending values. **/ | ||
| 30 | protected var _rawPrevTime:Number = -1; | ||
| 31 | /** @private **/ | ||
| 32 | protected var _pauseTime:Number; | ||
| 33 | |||
| 34 | /** Stores variables (things like alpha, y or whatever we're tweening as well as special properties like "onComplete"). **/ | ||
| 35 | public var vars:Object; | ||
| 36 | /** @private The tween has begun and is now active **/ | ||
| 37 | public var active:Boolean; | ||
| 38 | /** @private Flagged for garbage collection **/ | ||
| 39 | public var gc:Boolean; | ||
| 40 | /** @private Indicates whether or not init() has been called (where all the tween property start/end value information is recorded) **/ | ||
| 41 | public var initted:Boolean; | ||
| 42 | /** The parent timeline on which the tween/timeline is placed. By default, it uses the TweenLite.rootTimeline (or TweenLite.rootFramesTimeline for frames-based tweens/timelines). **/ | ||
| 43 | public var timeline:SimpleTimeline; | ||
| 44 | /** @private Start time in seconds (or frames for frames-based tweens/timelines), according to its position on its parent timeline **/ | ||
| 45 | public var cachedStartTime:Number; | ||
| 46 | /** @private The last rendered currentTime of this TweenCore. If a tween is going to repeat, its cachedTime will reset even though the cachedTotalTime continues linearly (or if it yoyos, the cachedTime may go forwards and backwards several times over the course of the tween). The cachedTime reflects the tween's "local" (which can never exceed the duration) time whereas the cachedTotalTime reflects the overall time. These will always match if the tween doesn't repeat/yoyo.**/ | ||
| 47 | public var cachedTime:Number; | ||
| 48 | /** @private The last rendered totalTime of this TweenCore. It is prefaced with "cached" because using a public property like this is faster than using the getter which is essentially a function call. If you want to update the value, you should always use the normal property, like myTween.totalTime = 0.5.**/ | ||
| 49 | public var cachedTotalTime:Number; | ||
| 50 | /** @private Prefaced with "cached" because using a public property like this is faster than using the getter which is essentially a function call. If you want to update the value, you should always use the normal property, like myTween.duration = 0.5.**/ | ||
| 51 | public var cachedDuration:Number; | ||
| 52 | /** @private Prefaced with "cached" because using a public property like this is faster than using the getter which is essentially a function call. If you want to update the value, you should always use the normal property, like myTween.totalDuration = 0.5.**/ | ||
| 53 | public var cachedTotalDuration:Number; | ||
| 54 | /** @private timeScale allows you to slow down or speed up a tween/timeline. 1 = normal speed, 0.5 = half speed, 2 = double speed, etc. It is prefaced with "cached" because using a public property like this is faster than using the getter which is essentially a function call. If you want to update the value, you should always use the normal property, like myTween.timeScale = 2**/ | ||
| 55 | public var cachedTimeScale:Number; | ||
| 56 | /** @private Indicates whether or not the tween is reversed. **/ | ||
| 57 | public var cachedReversed:Boolean; | ||
| 58 | /** @private Next TweenCore object in the linked list.**/ | ||
| 59 | public var nextNode:TweenCore; | ||
| 60 | /** @private Previous TweenCore object in the linked list**/ | ||
| 61 | public var prevNode:TweenCore; | ||
| 62 | /** @private When a TweenCore has been removed from its timeline, it is considered an orphan. When it it added to a timeline, it is no longer an orphan. We don't just set its "timeline" property to null because we need to always keep track of the timeline in case the TweenCore is enabled again by restart() or basically any operation that would cause it to become active again. "cachedGC" is different in that a TweenCore could be eligible for gc yet not removed from its timeline, like when a TimelineLite completes for example. **/ | ||
| 63 | public var cachedOrphan:Boolean; | ||
| 64 | /** @private Indicates that the duration or totalDuration may need refreshing (like if a TimelineLite's child had a change in duration or startTime). This is another performance booster because if the cache isn't dirty, we can quickly read from the cachedDuration and/or cachedTotalDuration **/ | ||
| 65 | public var cacheIsDirty:Boolean; | ||
| 66 | /** @private Quicker way to read the paused property. It is public for speed purposes. When setting the paused state, always use the regular "paused" property.**/ | ||
| 67 | public var cachedPaused:Boolean; | ||
| 68 | /** Place to store any data you want.**/ | ||
| 69 | public var data:*; | ||
| 70 | |||
| 71 | public function TweenCore(duration:Number=0, vars:Object=null) { | ||
| 72 | this.vars = (vars != null) ? vars : {}; | ||
| 73 | this.cachedDuration = this.cachedTotalDuration = duration; | ||
| 74 | _delay = (this.vars.delay) ? Number(this.vars.delay) : 0; | ||
| 75 | this.cachedTimeScale = (this.vars.timeScale) ? Number(this.vars.timeScale) : 1; | ||
| 76 | this.active = Boolean(duration == 0 && _delay == 0 && this.vars.immediateRender != false); | ||
| 77 | this.cachedTotalTime = this.cachedTime = 0; | ||
| 78 | this.data = this.vars.data; | ||
| 79 | |||
| 80 | if (!_classInitted) { | ||
| 81 | if (isNaN(TweenLite.rootFrame)) { | ||
| 82 | TweenLite.initClass(); | ||
| 83 | _classInitted = true; | ||
| 84 | } else { | ||
| 85 | return; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | var tl:SimpleTimeline = (this.vars.timeline is SimpleTimeline) ? this.vars.timeline : (this.vars.useFrames) ? TweenLite.rootFramesTimeline : TweenLite.rootTimeline; | ||
| 90 | this.cachedStartTime = tl.cachedTotalTime + _delay; | ||
| 91 | tl.addChild(this); | ||
| 92 | if (this.vars.reversed) { | ||
| 93 | this.cachedReversed = true; | ||
| 94 | } | ||
| 95 | if (this.vars.paused) { | ||
| 96 | this.paused = true; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | /** Starts playing forward from the current position. (essentially unpauses and makes sure that it is not reversed) **/ | ||
| 101 | public function play():void { | ||
| 102 | this.reversed = false; | ||
| 103 | this.paused = false; | ||
| 104 | } | ||
| 105 | |||
| 106 | /** Pauses the tween/timeline **/ | ||
| 107 | public function pause():void { | ||
| 108 | this.paused = true; | ||
| 109 | } | ||
| 110 | |||
| 111 | /** Starts playing from the current position without altering direction (forward or reversed). **/ | ||
| 112 | public function resume():void { | ||
| 113 | this.paused = false; | ||
| 114 | } | ||
| 115 | |||
| 116 | /** | ||
| 117 | * Restarts and begins playing forward. | ||
| 118 | * | ||
| 119 | * @param includeDelay Determines whether or not the delay (if any) is honored in the restart() | ||
| 120 | * @param suppressEvents If true, no events or callbacks will be triggered as the "virtual playhead" moves to the new position (onComplete, onUpdate, onReverseComplete, etc. of this tween/timeline and any of its child tweens/timelines won't be triggered, nor will any of the associated events be dispatched) | ||
| 121 | */ | ||
| 122 | public function restart(includeDelay:Boolean=false, suppressEvents:Boolean=true):void { | ||
| 123 | this.reversed = false; | ||
| 124 | this.paused = false; | ||
| 125 | this.setTotalTime((includeDelay) ? -_delay : 0, suppressEvents); | ||
| 126 | } | ||
| 127 | |||
| 128 | /** | ||
| 129 | * Reverses smoothly, adjusting the startTime to avoid any skipping. After being reversed, | ||
| 130 | * it will play backwards, exactly opposite from its forward orientation, meaning that, for example, a | ||
| 131 | * tween's easing equation will appear reversed as well. If a tween/timeline plays for 2 seconds and gets | ||
| 132 | * reversed, it will play for another 2 seconds to return to the beginning. | ||
| 133 | * | ||
| 134 | * @param forceResume If true, it will resume() immediately upon reversing. Otherwise its paused state will remain unchanged. | ||
| 135 | */ | ||
| 136 | public function reverse(forceResume:Boolean=true):void { | ||
| 137 | this.reversed = true; | ||
| 138 | if (forceResume) { | ||
| 139 | this.paused = false; | ||
| 140 | } else if (this.gc) { | ||
| 141 | this.setEnabled(true, false); | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | /** | ||
| 146 | * @private | ||
| 147 | * Renders the tween/timeline at a particular time (or frame number for frames-based tweens) | ||
| 148 | * WITHOUT changing its startTime. For example, if a tween's duration | ||
| 149 | * is 3, <code>renderTime(1.5)</code> would render it at the halfway finished point. | ||
| 150 | * | ||
| 151 | * @param time time in seconds (or frame number for frames-based tweens/timelines) to render. | ||
| 152 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 153 | * @param force Normally the tween will skip rendering if the time matches the cachedTotalTime (to improve performance), but if force is true, it forces a render. This is primarily used internally for tweens with durations of zero in TimelineLite/Max instances. | ||
| 154 | */ | ||
| 155 | public function renderTime(time:Number, suppressEvents:Boolean=false, force:Boolean=false):void { | ||
| 156 | |||
| 157 | } | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Forces the tween/timeline to completion. | ||
| 161 | * | ||
| 162 | * @param skipRender to skip rendering the final state of the tween, set skipRender to true. | ||
| 163 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 164 | */ | ||
| 165 | public function complete(skipRender:Boolean=false, suppressEvents:Boolean=false):void { | ||
| 166 | if (!skipRender) { | ||
| 167 | renderTime(this.totalDuration, suppressEvents, false); //just to force the final render | ||
| 168 | return; //renderTime() will call complete() again, so just return here. | ||
| 169 | } | ||
| 170 | if (this.timeline.autoRemoveChildren) { | ||
| 171 | this.setEnabled(false, false); | ||
| 172 | } else { | ||
| 173 | this.active = false; | ||
| 174 | } | ||
| 175 | if (!suppressEvents) { | ||
| 176 | if (this.vars.onComplete && this.cachedTotalTime == this.cachedTotalDuration && !this.cachedReversed) { //note: remember that tweens can have a duration of zero in which case their cachedTime and cachedDuration would always match. | ||
| 177 | this.vars.onComplete.apply(null, this.vars.onCompleteParams); | ||
| 178 | } else if (this.cachedReversed && this.cachedTotalTime == 0 && this.vars.onReverseComplete) { | ||
| 179 | this.vars.onReverseComplete.apply(null, this.vars.onReverseCompleteParams); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | /** | ||
| 185 | * Clears any initialization data (like starting values in tweens) which can be useful if, for example, | ||
| 186 | * you want to restart it without reverting to any previously recorded starting values. When you invalidate() | ||
| 187 | * a tween/timeline, it will be re-initialized the next time it renders and its <code>vars</code> object will be re-parsed. | ||
| 188 | * The timing of the tween/timeline (duration, startTime, delay) will NOT be affected. Another example would be if you | ||
| 189 | * have a <code>TweenMax(mc, 1, {x:100, y:100})</code> that ran when mc.x and mc.y were initially at 0, but now mc.x | ||
| 190 | * and mc.y are 200 and you want them tween to 100 again, you could simply <code>invalidate()</code> the tween and | ||
| 191 | * <code>restart()</code> it. Without invalidating first, restarting it would cause the values jump back to 0 immediately | ||
| 192 | * (where they started when the tween originally began). When you invalidate a timeline, it automatically invalidates | ||
| 193 | * all of its children. | ||
| 194 | **/ | ||
| 195 | public function invalidate():void { | ||
| 196 | |||
| 197 | } | ||
| 198 | |||
| 199 | /** | ||
| 200 | * @private | ||
| 201 | * If a tween/timeline is enabled, it is eligible to be rendered (unless it is paused). Setting enabled to | ||
| 202 | * false essentially removes it from its parent timeline and stops protecting it from garbage collection. | ||
| 203 | * | ||
| 204 | * @param enabled Enabled state of the tween/timeline | ||
| 205 | * @param ignoreTimeline By default, the tween/timeline will remove itself from its parent timeline when it is disabled, and add itself when it is enabled, but this parameter allows you to override that behavior. | ||
| 206 | * @return Boolean value indicating whether or not important properties may have changed when the TweenCore was enabled/disabled. For example, when a motionBlur (plugin) is disabled, it swaps out a BitmapData for the target and may alter the alpha. We need to know this in order to determine whether or not a new tween that is overwriting this one should be re-initted() with the changed properties. | ||
| 207 | **/ | ||
| 208 | public function setEnabled(enabled:Boolean, ignoreTimeline:Boolean=false):Boolean { | ||
| 209 | this.gc = !enabled; | ||
| 210 | if (enabled) { | ||
| 211 | this.active = Boolean(!this.cachedPaused && this.cachedTotalTime > 0 && this.cachedTotalTime < this.cachedTotalDuration); | ||
| 212 | if (!ignoreTimeline && this.cachedOrphan) { | ||
| 213 | this.timeline.addChild(this); | ||
| 214 | } | ||
| 215 | } else { | ||
| 216 | this.active = false; | ||
| 217 | if (!ignoreTimeline && !this.cachedOrphan) { | ||
| 218 | this.timeline.remove(this, true); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | return false; | ||
| 222 | } | ||
| 223 | |||
| 224 | /** Kills the tween/timeline, stopping it immediately. **/ | ||
| 225 | public function kill():void { | ||
| 226 | setEnabled(false, false); | ||
| 227 | } | ||
| 228 | |||
| 229 | /** | ||
| 230 | * @private | ||
| 231 | * Sets the cacheIsDirty property of all anscestor timelines (and optionally this tween/timeline too). Setting | ||
| 232 | * the cacheIsDirty property to true forces any necessary recalculation of its cachedDuration and cachedTotalDuration | ||
| 233 | * properties and sorts the affected timelines' children TweenCores so that they're in the proper order | ||
| 234 | * next time the duration or totalDuration is requested. We don't just recalculate them immediately because | ||
| 235 | * it can be much faster to do it this way. | ||
| 236 | * | ||
| 237 | * @param includeSelf indicates whether or not this tween's cacheIsDirty property should be affected. | ||
| 238 | */ | ||
| 239 | protected function setDirtyCache(includeSelf:Boolean=true):void { | ||
| 240 | var tween:TweenCore = (includeSelf) ? this : this.timeline; | ||
| 241 | while (tween) { | ||
| 242 | tween.cacheIsDirty = true; | ||
| 243 | tween = tween.timeline; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | /** | ||
| 248 | * @private | ||
| 249 | * Sort of like placing the local "playhead" at a particular totalTime and then aligning it with | ||
| 250 | * the parent timeline's "playhead" so that rendering continues from that point smoothly. This | ||
| 251 | * changes the cachedStartTime. | ||
| 252 | * | ||
| 253 | * @param time Time that should be rendered (includes any repeats and repeatDelays for TimelineMax) | ||
| 254 | * @param suppressEvents If true, no events or callbacks will be triggered for this render (like onComplete, onUpdate, onReverseComplete, etc.) | ||
| 255 | **/ | ||
| 256 | protected function setTotalTime(time:Number, suppressEvents:Boolean=false):void { | ||
| 257 | if (this.timeline) { | ||
| 258 | var tlTime:Number = (_pauseTime || _pauseTime == 0) ? _pauseTime : this.timeline.cachedTotalTime; | ||
| 259 | if (this.cachedReversed) { | ||
| 260 | var dur:Number = (this.cacheIsDirty) ? this.totalDuration : this.cachedTotalDuration; | ||
| 261 | this.cachedStartTime = tlTime - ((dur - time) / this.cachedTimeScale); | ||
| 262 | } else { | ||
| 263 | this.cachedStartTime = tlTime - (time / this.cachedTimeScale); | ||
| 264 | } | ||
| 265 | if (!this.timeline.cacheIsDirty) { //for performance improvement. If the parent's cache is already dirty, it already took care of marking the anscestors as dirty too, so skip the function call here. | ||
| 266 | setDirtyCache(false); | ||
| 267 | } | ||
| 268 | if (this.cachedTotalTime != time) { | ||
| 269 | renderTime(time, suppressEvents, false); | ||
| 270 | } | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | |||
| 275 | //---- GETTERS / SETTERS ------------------------------------------------------------ | ||
| 276 | |||
| 277 | /** | ||
| 278 | * Length of time in seconds (or frames for frames-based tweens/timelines) before the tween should begin. | ||
| 279 | * The tween's starting values are not determined until after the delay has expired (except in from() tweens) | ||
| 280 | **/ | ||
| 281 | public function get delay():Number { | ||
| 282 | return _delay; | ||
| 283 | } | ||
| 284 | |||
| 285 | public function set delay(n:Number):void { | ||
| 286 | this.startTime += (n - _delay); | ||
| 287 | _delay = n; | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * Duration of the tween in seconds (or frames for frames-based tweens/timelines) not including any repeats | ||
| 292 | * or repeatDelays. <code>totalDuration</code>, by contrast, does include repeats and repeatDelays. | ||
| 293 | **/ | ||
| 294 | public function get duration():Number { | ||
| 295 | return this.cachedDuration; | ||
| 296 | } | ||
| 297 | |||
| 298 | public function set duration(n:Number):void { | ||
| 299 | this.cachedDuration = this.cachedTotalDuration = n; | ||
| 300 | setDirtyCache(false); | ||
| 301 | } | ||
| 302 | |||
| 303 | /** | ||
| 304 | * Duration of the tween in seconds (or frames for frames-based tweens/timelines) including any repeats | ||
| 305 | * or repeatDelays (which are only available on TweenMax and TimelineMax). <code>duration</code>, by contrast, does | ||
| 306 | * <b>NOT</b> include repeats and repeatDelays. So if a TweenMax's <code>duration</code> is 1 and it has a repeat of 2, the <code>totalDuration</code> would be 3. | ||
| 307 | **/ | ||
| 308 | public function get totalDuration():Number { | ||
| 309 | return this.cachedTotalDuration; | ||
| 310 | } | ||
| 311 | |||
| 312 | public function set totalDuration(n:Number):void { | ||
| 313 | this.duration = n; | ||
| 314 | } | ||
| 315 | |||
| 316 | /** | ||
| 317 | * Most recently rendered time (or frame for frames-based tweens/timelines) according to its | ||
| 318 | * <code>duration</code>. <code>totalTime</code>, by contrast, is based on its <code>totalDuration</code> | ||
| 319 | * which includes repeats and repeatDelays. Since TweenLite and TimelineLite don't offer | ||
| 320 | * <code>repeat</code> and <code>repeatDelay</code> functionality, <code>currentTime</code> | ||
| 321 | * and <code>totalTime</code> will always be the same but in TweenMax or TimelineMax, they | ||
| 322 | * could be different. For example, if a TimelineMax instance has a duration | ||
| 323 | * of 5 a repeat of 1 (meaning its <code>totalDuration</code> is 10), at the end of the second cycle, | ||
| 324 | * <code>currentTime</code> would be 5 whereas <code>totalTime</code> would be 10. If you tracked both | ||
| 325 | * properties over the course of the tween, you'd see <code>currentTime</code> go from 0 to 5 twice (one for each | ||
| 326 | * cycle) in the same time it takes <code>totalTime</code> go from 0 to 10. | ||
| 327 | **/ | ||
| 328 | public function get currentTime():Number { | ||
| 329 | return this.cachedTime; | ||
| 330 | } | ||
| 331 | |||
| 332 | public function set currentTime(n:Number):void { | ||
| 333 | setTotalTime(n, false); | ||
| 334 | } | ||
| 335 | |||
| 336 | /** | ||
| 337 | * Most recently rendered time (or frame for frames-based tweens/timelines) according to its | ||
| 338 | * <code>totalDuration</code>. <code>currentTime</code>, by contrast, is based on its <code>duration</code> | ||
| 339 | * which does NOT include repeats and repeatDelays. Since TweenLite and TimelineLite don't offer | ||
| 340 | * <code>repeat</code> and <code>repeatDelay</code> functionality, <code>currentTime</code> | ||
| 341 | * and <code>totalTime</code> will always be the same but in TweenMax or TimelineMax, they | ||
| 342 | * could be different. For example, if a TimelineMax instance has a duration | ||
| 343 | * of 5 a repeat of 1 (meaning its <code>totalDuration</code> is 10), at the end of the second cycle, | ||
| 344 | * <code>currentTime</code> would be 5 whereas <code>totalTime</code> would be 10. If you tracked both | ||
| 345 | * properties over the course of the tween, you'd see <code>currentTime</code> go from 0 to 5 twice (one for each | ||
| 346 | * cycle) in the same time it takes <code>totalTime</code> go from 0 to 10. | ||
| 347 | **/ | ||
| 348 | public function get totalTime():Number { | ||
| 349 | return this.cachedTotalTime; | ||
| 350 | } | ||
| 351 | |||
| 352 | public function set totalTime(n:Number):void { | ||
| 353 | setTotalTime(n, false); | ||
| 354 | } | ||
| 355 | |||
| 356 | /** Start time in seconds (or frames for frames-based tweens/timelines), according to its position on its parent timeline **/ | ||
| 357 | public function get startTime():Number { | ||
| 358 | return this.cachedStartTime; | ||
| 359 | } | ||
| 360 | |||
| 361 | public function set startTime(n:Number):void { | ||
| 362 | var adjust:Boolean = Boolean(this.timeline != null && (n != this.cachedStartTime || this.gc)); | ||
| 363 | this.cachedStartTime = n; | ||
| 364 | if (adjust) { | ||
| 365 | this.timeline.addChild(this); //ensures that any necessary re-sequencing of TweenCores in the timeline occurs to make sure the rendering order is correct. | ||
| 366 | } | ||
| 367 | } | ||
| 368 | |||
| 369 | /** Indicates the reversed state of the tween/timeline. This value is not affected by <code>yoyo</code> repeats and it does not take into account the reversed state of anscestor timelines. So for example, a tween that is not reversed might appear reversed if its parent timeline (or any ancenstor timeline) is reversed. **/ | ||
| 370 | public function get reversed():Boolean { | ||
| 371 | return this.cachedReversed; | ||
| 372 | } | ||
| 373 | |||
| 374 | public function set reversed(b:Boolean):void { | ||
| 375 | if (b != this.cachedReversed) { | ||
| 376 | this.cachedReversed = b; | ||
| 377 | setTotalTime(this.cachedTotalTime, true); | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | /** Indicates the paused state of the tween/timeline. This does not take into account anscestor timelines. So for example, a tween that is not paused might appear paused if its parent timeline (or any ancenstor timeline) is paused. **/ | ||
| 382 | public function get paused():Boolean { | ||
| 383 | return this.cachedPaused; | ||
| 384 | } | ||
| 385 | |||
| 386 | public function set paused(b:Boolean):void { | ||
| 387 | if (b != this.cachedPaused && this.timeline) { | ||
| 388 | if (b) { | ||
| 389 | _pauseTime = this.timeline.rawTime; | ||
| 390 | } else { | ||
| 391 | this.cachedStartTime += this.timeline.rawTime - _pauseTime; | ||
| 392 | _pauseTime = NaN; | ||
| 393 | setDirtyCache(false); | ||
| 394 | } | ||
| 395 | this.cachedPaused = b; | ||
| 396 | this.active = Boolean(!this.cachedPaused && this.cachedTotalTime > 0 && this.cachedTotalTime < this.cachedTotalDuration); | ||
| 397 | } | ||
| 398 | if (!b && this.gc) { | ||
| 399 | this.setTotalTime(this.cachedTotalTime, false); | ||
| 400 | this.setEnabled(true, false); | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | } | ||
| 405 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* | ||
| 2 | VERSION: 1.01 | ||
| 3 | DATE: 1/29/2009 | ||
| 4 | ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | DESCRIPTION: | ||
| 6 | This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 7 | strict data typing and code hinting (in most code editors) for filter tweens. See the documentation | ||
| 8 | in TweenMaxVars for more information. | ||
| 9 | |||
| 10 | USAGE: | ||
| 11 | |||
| 12 | Instead of TweenMax.to(my_mc, 1, {bevelFilter:{distance:5, blurX:10, blurY:10, strength:2}, onComplete:myFunction}), you could use this utility like: | ||
| 13 | |||
| 14 | var myVars:TweenMaxVars = new TweenMaxVars(); | ||
| 15 | myVars.bevelFilter = new BevelFilterVars(5, 10, 10, 2); | ||
| 16 | myVars.onComplete = myFunction; | ||
| 17 | TweenMax.to(my_mc, 1, myVars); | ||
| 18 | |||
| 19 | |||
| 20 | NOTES: | ||
| 21 | - This utility is completely optional. If you prefer the shorter synatax in the regular TweenMax class, feel | ||
| 22 | free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. | ||
| 23 | - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly | ||
| 24 | data typed) syntax, like TweenMax.to(my_mc, 1, {bevelFilter:{blurX:"-5", blurY:"3"}}); | ||
| 25 | |||
| 26 | AUTHOR: Jack Doyle, jack@greensock.com | ||
| 27 | Copyright 2010, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 28 | */ | ||
| 29 | |||
| 30 | |||
| 31 | package com.greensock.data { | ||
| 32 | |||
| 33 | public class BevelFilterVars extends FilterVars { | ||
| 34 | public var distance:Number; | ||
| 35 | public var blurX:Number; | ||
| 36 | public var blurY:Number; | ||
| 37 | public var strength:Number; | ||
| 38 | public var angle:Number; | ||
| 39 | public var highlightAlpha:Number; | ||
| 40 | public var shadowAlpha:Number; | ||
| 41 | |||
| 42 | public function BevelFilterVars(distance:Number=4, blurX:Number=4, blurY:Number=4, strength:Number=1, angle:Number=45, highlightAlpha:Number=1, highlightColor:uint=0xFFFFFF, shadowAlpha:Number=1, shadowColor:uint=0x000000, quality:uint=2, remove:Boolean=false, index:int=-1, addFilter:Boolean=false) { | ||
| 43 | super(remove, index, addFilter); | ||
| 44 | this.distance = distance; | ||
| 45 | this.blurX = blurX; | ||
| 46 | this.blurY = blurY; | ||
| 47 | this.strength = strength; | ||
| 48 | this.angle = angle; | ||
| 49 | this.highlightAlpha = highlightAlpha; | ||
| 50 | this.highlightColor = highlightColor; | ||
| 51 | this.shadowAlpha = shadowAlpha; | ||
| 52 | this.shadowColor = shadowColor; | ||
| 53 | this.quality = quality; | ||
| 54 | } | ||
| 55 | |||
| 56 | override protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 57 | super.initEnumerables(nulls, numbers.concat(["distance","blurX","blurY","strength","angle","highlightAlpha","shadowAlpha"])); | ||
| 58 | } | ||
| 59 | |||
| 60 | public static function create(vars:Object):BevelFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) | ||
| 61 | if (vars is BevelFilterVars) { | ||
| 62 | return vars as BevelFilterVars; | ||
| 63 | } | ||
| 64 | return new BevelFilterVars(vars.distance || 0, | ||
| 65 | vars.blurX || 0, | ||
| 66 | vars.blurY || 0, | ||
| 67 | (vars.strength == null) ? 1 : vars.strength, | ||
| 68 | (vars.angle == null) ? 45 : vars.angle, | ||
| 69 | (vars.highlightAlpha == null) ? 1 : vars.highlightAlpha, | ||
| 70 | (vars.highlightColor == null) ? 0xFFFFFF : vars.highlightColor, | ||
| 71 | (vars.shadowAlpha == null) ? 1 : vars.shadowAlpha, | ||
| 72 | (vars.shadowColor == null) ? 0xFFFFFF : vars.shadowColor, | ||
| 73 | vars.quality || 2, | ||
| 74 | vars.remove || false, | ||
| 75 | (vars.index == null) ? -1 : vars.index, | ||
| 76 | vars.addFilter || false); | ||
| 77 | } | ||
| 78 | |||
| 79 | //---- GETTERS / SETTERS -------------------------------------------------------------------------------------------- | ||
| 80 | |||
| 81 | /** Highlight color. **/ | ||
| 82 | public function get highlightColor():uint { | ||
| 83 | return uint(_values.highlightColor); | ||
| 84 | } | ||
| 85 | public function set highlightColor(value:uint):void { | ||
| 86 | setProp("highlightColor", value); | ||
| 87 | } | ||
| 88 | |||
| 89 | /** Shadow color. **/ | ||
| 90 | public function get shadowColor():uint { | ||
| 91 | return uint(_values.shadowColor); | ||
| 92 | } | ||
| 93 | public function set shadowColor(value:uint):void { | ||
| 94 | setProp("shadowColor", value); | ||
| 95 | } | ||
| 96 | |||
| 97 | /** Quality (1, 2, or 3). **/ | ||
| 98 | public function get quality():uint { | ||
| 99 | return uint(_values.quality); | ||
| 100 | } | ||
| 101 | public function set quality(value:uint):void { | ||
| 102 | setProp("quality", value); | ||
| 103 | } | ||
| 104 | |||
| 105 | } | ||
| 106 | |||
| 107 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* | ||
| 2 | VERSION: 1.01 | ||
| 3 | DATE: 1/29/2009 | ||
| 4 | ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | DESCRIPTION: | ||
| 6 | This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 7 | strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in | ||
| 8 | the TweenLiteVars or TweenMaxVars for more information. | ||
| 9 | |||
| 10 | USAGE: | ||
| 11 | |||
| 12 | Instead of TweenMax.to(my_mc, 1, {blurFilter:{blurX:10, blurY:10}, onComplete:myFunction}), you could use this utility like: | ||
| 13 | |||
| 14 | var myVars:TweenMaxVars = new TweenMaxVars(); | ||
| 15 | myVars.blurFilter = new BlurFilterVars(10, 10); | ||
| 16 | myVars.onComplete = myFunction; | ||
| 17 | TweenMax.to(my_mc, 1, myVars); | ||
| 18 | |||
| 19 | |||
| 20 | NOTES: | ||
| 21 | - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel | ||
| 22 | free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. | ||
| 23 | - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly | ||
| 24 | data typed) syntax, like TweenMax.to(my_mc, 1, {blurFilter:{blurX:"-5", blurY:"3"}}); | ||
| 25 | |||
| 26 | AUTHOR: Jack Doyle, jack@greensock.com | ||
| 27 | Copyright 2010, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 28 | */ | ||
| 29 | |||
| 30 | |||
| 31 | package com.greensock.data { | ||
| 32 | public class BlurFilterVars extends FilterVars { | ||
| 33 | public var blurX:Number; | ||
| 34 | public var blurY:Number; | ||
| 35 | |||
| 36 | public function BlurFilterVars(blurX:Number=10, blurY:Number=10, quality:uint=2, remove:Boolean=false, index:int=-1, addFilter:Boolean=false) { | ||
| 37 | super(remove, index, addFilter); | ||
| 38 | this.blurX = blurX; | ||
| 39 | this.blurY = blurY; | ||
| 40 | this.quality = quality; | ||
| 41 | } | ||
| 42 | |||
| 43 | override protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 44 | super.initEnumerables(nulls, numbers.concat(["blurX","blurY"])); | ||
| 45 | } | ||
| 46 | |||
| 47 | public static function create(vars:Object):BlurFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) | ||
| 48 | if (vars is BlurFilterVars) { | ||
| 49 | return vars as BlurFilterVars; | ||
| 50 | } | ||
| 51 | return new BlurFilterVars(vars.blurX || 0, | ||
| 52 | vars.blurY || 0, | ||
| 53 | vars.quality || 2, | ||
| 54 | vars.remove || false, | ||
| 55 | (vars.index == null) ? -1 : vars.index, | ||
| 56 | vars.addFilter || false); | ||
| 57 | } | ||
| 58 | |||
| 59 | //---- GETTERS / SETTERS ------------------------------------------------------------------------------ | ||
| 60 | |||
| 61 | /** Quality (1, 2, or 3). **/ | ||
| 62 | public function get quality():uint { | ||
| 63 | return uint(_values.quality); | ||
| 64 | } | ||
| 65 | public function set quality(value:uint):void { | ||
| 66 | setProp("quality", value); | ||
| 67 | } | ||
| 68 | |||
| 69 | } | ||
| 70 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* | ||
| 2 | VERSION: 1.01 | ||
| 3 | DATE: 1/29/2009 | ||
| 4 | ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | DESCRIPTION: | ||
| 6 | This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 7 | strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in | ||
| 8 | the TweenLiteVars or TweenMaxVars for more information. | ||
| 9 | |||
| 10 | USAGE: | ||
| 11 | |||
| 12 | Instead of TweenMax.to(my_mc, 1, {colorMatrixFilter:{colorize:0xFF0000, amount:0.5}, onComplete:myFunction}), you could use this utility like: | ||
| 13 | |||
| 14 | var myVars:TweenMaxVars = new TweenMaxVars(); | ||
| 15 | myVars.colorMatrixFilter = new ColorMatrixFilterVars(0xFF0000, 0.5); | ||
| 16 | myVars.onComplete = myFunction; | ||
| 17 | TweenMax.to(my_mc, 1, myVars); | ||
| 18 | |||
| 19 | |||
| 20 | NOTES: | ||
| 21 | - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel | ||
| 22 | free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. | ||
| 23 | - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly | ||
| 24 | data typed) syntax, like TweenMax.to(my_mc, 1, {colorMatrixFilter:{contrast:0.5, relative:true}}); | ||
| 25 | |||
| 26 | AUTHOR: Jack Doyle, jack@greensock.com | ||
| 27 | Copyright 2010, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 28 | */ | ||
| 29 | |||
| 30 | |||
| 31 | package com.greensock.data { | ||
| 32 | import com.greensock.plugins.*; | ||
| 33 | |||
| 34 | public class ColorMatrixFilterVars extends FilterVars { | ||
| 35 | protected static var _ID_MATRIX:Array = [1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0]; | ||
| 36 | protected static var _lumR:Number = 0.212671; //Red constant - used for a few color matrix filter functions | ||
| 37 | protected static var _lumG:Number = 0.715160; //Green constant - used for a few color matrix filter functions | ||
| 38 | protected static var _lumB:Number = 0.072169; //Blue constant - used for a few color matrix filter functions | ||
| 39 | |||
| 40 | public var matrix:Array; | ||
| 41 | |||
| 42 | public function ColorMatrixFilterVars(colorize:uint=0xFFFFFF, amount:Number=1, saturation:Number=1, contrast:Number=1, brightness:Number=1, hue:Number=0, threshold:Number=-1, remove:Boolean=false, index:int=-1, addFilter:Boolean=false) { | ||
| 43 | super(remove, index, addFilter); | ||
| 44 | this.matrix = _ID_MATRIX.slice(); | ||
| 45 | if (brightness != 1) { | ||
| 46 | setBrightness(brightness); | ||
| 47 | } | ||
| 48 | if (contrast != 1) { | ||
| 49 | setContrast(contrast); | ||
| 50 | } | ||
| 51 | if (hue != 0) { | ||
| 52 | setHue(hue); | ||
| 53 | } | ||
| 54 | if (saturation != 1) { | ||
| 55 | setSaturation(saturation); | ||
| 56 | } | ||
| 57 | if (threshold != -1) { | ||
| 58 | setThreshold(threshold); | ||
| 59 | } | ||
| 60 | if (colorize != 0xFFFFFF) { | ||
| 61 | setColorize(colorize, amount); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | override protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 66 | super.initEnumerables(nulls.concat(["matrix"]), numbers); | ||
| 67 | } | ||
| 68 | |||
| 69 | public function setBrightness(n:Number):void { | ||
| 70 | this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setBrightness(this.matrix, n); | ||
| 71 | } | ||
| 72 | public function setContrast(n:Number):void { | ||
| 73 | this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setContrast(this.matrix, n); | ||
| 74 | } | ||
| 75 | public function setHue(n:Number):void { | ||
| 76 | this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setHue(this.matrix, n); | ||
| 77 | } | ||
| 78 | public function setSaturation(n:Number):void { | ||
| 79 | this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setSaturation(this.matrix, n); | ||
| 80 | } | ||
| 81 | public function setThreshold(n:Number):void { | ||
| 82 | this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setThreshold(this.matrix, n); | ||
| 83 | } | ||
| 84 | public function setColorize(color:uint, amount:Number=1):void { | ||
| 85 | this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.colorize(this.matrix, color, amount); | ||
| 86 | } | ||
| 87 | |||
| 88 | public static function create(vars:Object):ColorMatrixFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) | ||
| 89 | var v:ColorMatrixFilterVars; | ||
| 90 | if (vars is ColorMatrixFilterVars) { | ||
| 91 | v = vars as ColorMatrixFilterVars; | ||
| 92 | } else if (vars.matrix != null) { | ||
| 93 | v = new ColorMatrixFilterVars(); | ||
| 94 | v.matrix = vars.matrix; | ||
| 95 | } else { | ||
| 96 | v = new ColorMatrixFilterVars(vars.colorize || 0xFFFFFF, | ||
| 97 | (vars.amount == null) ? 1 : vars.amount, | ||
| 98 | (vars.saturation == null) ? 1 : vars.saturation, | ||
| 99 | (vars.contrast == null) ? 1 : vars.contrast, | ||
| 100 | (vars.brightness == null) ? 1 : vars.brightness, | ||
| 101 | vars.hue || 0, | ||
| 102 | (vars.threshold == null) ? -1 : vars.threshold, | ||
| 103 | vars.remove || false, | ||
| 104 | (vars.index == null) ? -1 : vars.index, | ||
| 105 | vars.addFilter || false); | ||
| 106 | } | ||
| 107 | return v; | ||
| 108 | } | ||
| 109 | |||
| 110 | |||
| 111 | } | ||
| 112 | |||
| 113 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* | ||
| 2 | VERSION: 1.0 | ||
| 3 | DATE: 1/29/2009 | ||
| 4 | ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | DESCRIPTION: | ||
| 6 | This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 7 | strict data typing and code hinting (in most code editors) for colorTransform tweens. See the documentation in | ||
| 8 | the TweenLiteVars or TweenMaxVars for more information. | ||
| 9 | |||
| 10 | USAGE: | ||
| 11 | |||
| 12 | Instead of TweenMax.to(my_mc, 1, {colorTransform:{exposure:2}}, onComplete:myFunction}), you could use this utility like: | ||
| 13 | |||
| 14 | var myVars:TweenMaxVars = new TweenMaxVars(); | ||
| 15 | var ct:ColorTransformVars = new ColorTransformVars(); | ||
| 16 | ct.exposure = 2; | ||
| 17 | myVars.colorTransform = ct; | ||
| 18 | myVars.onComplete = myFunction; | ||
| 19 | TweenMax.to(my_mc, 1, myVars); | ||
| 20 | |||
| 21 | |||
| 22 | NOTES: | ||
| 23 | - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel | ||
| 24 | free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. | ||
| 25 | - You cannot define relative tween values with this utility. | ||
| 26 | |||
| 27 | AUTHOR: Jack Doyle, jack@greensock.com | ||
| 28 | Copyright 2010, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 29 | */ | ||
| 30 | |||
| 31 | |||
| 32 | package com.greensock.data { | ||
| 33 | |||
| 34 | public class ColorTransformVars extends VarsCore { | ||
| 35 | public var tintAmount:Number; | ||
| 36 | public var exposure:Number; | ||
| 37 | public var brightness:Number; | ||
| 38 | public var redMultiplier:Number; | ||
| 39 | public var redOffset:Number; | ||
| 40 | public var greenMultiplier:Number; | ||
| 41 | public var greenOffset:Number; | ||
| 42 | public var blueMultiplier:Number; | ||
| 43 | public var blueOffset:Number; | ||
| 44 | public var alphaMultiplier:Number; | ||
| 45 | public var alphaOffset:Number; | ||
| 46 | |||
| 47 | public function ColorTransformVars(tint:Number=NaN, tintAmount:Number=NaN, exposure:Number=NaN, brightness:Number=NaN, redMultiplier:Number=NaN, greenMultiplier:Number=NaN, blueMultiplier:Number=NaN, alphaMultiplier:Number=NaN, redOffset:Number=NaN, greenOffset:Number=NaN, blueOffset:Number=NaN, alphaOffset:Number=NaN) { | ||
| 48 | super(); | ||
| 49 | if (tint || tint == 0) { //faster than !isNaN()) | ||
| 50 | this.tint = uint(tint); | ||
| 51 | } | ||
| 52 | if (tintAmount || tintAmount == 0) { | ||
| 53 | this.tintAmount = tintAmount; | ||
| 54 | } | ||
| 55 | if (exposure || exposure == 0) { | ||
| 56 | this.exposure = exposure; | ||
| 57 | } | ||
| 58 | if (brightness || brightness == 0) { | ||
| 59 | this.brightness = brightness; | ||
| 60 | } | ||
| 61 | if (redMultiplier || redMultiplier == 0) { | ||
| 62 | this.redMultiplier = redMultiplier; | ||
| 63 | } | ||
| 64 | if (greenMultiplier || greenMultiplier == 0) { | ||
| 65 | this.greenMultiplier = greenMultiplier; | ||
| 66 | } | ||
| 67 | if (blueMultiplier || blueMultiplier == 0) { | ||
| 68 | this.blueMultiplier = blueMultiplier; | ||
| 69 | } | ||
| 70 | if (alphaMultiplier || alphaMultiplier == 0) { | ||
| 71 | this.alphaMultiplier = alphaMultiplier; | ||
| 72 | } | ||
| 73 | if (redOffset || redOffset == 0) { | ||
| 74 | this.redOffset = redOffset; | ||
| 75 | } | ||
| 76 | if (greenOffset || greenOffset == 0) { | ||
| 77 | this.greenOffset = greenOffset; | ||
| 78 | } | ||
| 79 | if (blueOffset || blueOffset == 0) { | ||
| 80 | this.blueOffset = blueOffset; | ||
| 81 | } | ||
| 82 | if (alphaOffset || alphaOffset == 0) { | ||
| 83 | this.alphaOffset = alphaOffset; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | override protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 88 | super.initEnumerables(nulls, | ||
| 89 | numbers.concat(["tintAmount","exposure","brightness","redMultiplier","redOffset", | ||
| 90 | "greenMultiplier","greenOffset","blueMultiplier","blueOffset", | ||
| 91 | "alphaMultiplier","alphaOffset"])); | ||
| 92 | } | ||
| 93 | |||
| 94 | public static function create(vars:Object):ColorTransformVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) | ||
| 95 | if (vars is ColorTransformVars) { | ||
| 96 | return vars as ColorTransformVars; | ||
| 97 | } | ||
| 98 | return new ColorTransformVars(vars.tint, | ||
| 99 | vars.tintAmount, | ||
| 100 | vars.exposure, | ||
| 101 | vars.brightness, | ||
| 102 | vars.redMultiplier, | ||
| 103 | vars.greenMultiplier, | ||
| 104 | vars.blueMultiplier, | ||
| 105 | vars.alphaMultiplier, | ||
| 106 | vars.redOffset, | ||
| 107 | vars.greenOffset, | ||
| 108 | vars.blueOffset, | ||
| 109 | vars.alphaOffset); | ||
| 110 | } | ||
| 111 | |||
| 112 | //---- GETTERS / SETTERS ------------------------------------------------------------------------------ | ||
| 113 | |||
| 114 | /** To change a DisplayObject's tint, set this to the hex value of the color you'd like the DisplayObject to end up at(or begin at if you're using TweenLite.from()). An example hex value would be 0xFF0000. If you'd like to remove the tint from a DisplayObject, use the removeTint special property. **/ | ||
| 115 | public function get tint():uint { | ||
| 116 | return uint(_values.tint); | ||
| 117 | } | ||
| 118 | public function set tint(value:uint):void { | ||
| 119 | setProp("tint", value); | ||
| 120 | } | ||
| 121 | |||
| 122 | |||
| 123 | } | ||
| 124 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* | ||
| 2 | VERSION: 1.01 | ||
| 3 | DATE: 1/29/2009 | ||
| 4 | ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | DESCRIPTION: | ||
| 6 | This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 7 | strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in | ||
| 8 | the TweenLiteVars or TweenMaxVars for more information. | ||
| 9 | |||
| 10 | USAGE: | ||
| 11 | |||
| 12 | Instead of TweenMax.to(my_mc, 1, {dropShadowFilter:{distance:5, blurX:10, blurY:10, color:0xFF0000}, onComplete:myFunction}), you could use this utility like: | ||
| 13 | |||
| 14 | var myVars:TweenMaxVars = new TweenMaxVars(); | ||
| 15 | myVars.dropShadowFilter = new DropShadowFilterVars(5, 10, 10, 1, 45, 0xFF0000); | ||
| 16 | myVars.onComplete = myFunction; | ||
| 17 | TweenMax.to(my_mc, 1, myVars); | ||
| 18 | |||
| 19 | |||
| 20 | NOTES: | ||
| 21 | - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel | ||
| 22 | free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. | ||
| 23 | - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly | ||
| 24 | data typed) syntax, like TweenMax.to(my_mc, 1, {dropShadowFilter:{blurX:"-5", blurY:"3"}}); | ||
| 25 | |||
| 26 | AUTHOR: Jack Doyle, jack@greensock.com | ||
| 27 | Copyright 2010, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 28 | */ | ||
| 29 | |||
| 30 | |||
| 31 | package com.greensock.data { | ||
| 32 | |||
| 33 | public class DropShadowFilterVars extends BlurFilterVars { | ||
| 34 | public var distance:Number; | ||
| 35 | public var alpha:Number; | ||
| 36 | public var angle:Number; | ||
| 37 | public var strength:Number; | ||
| 38 | |||
| 39 | public function DropShadowFilterVars(distance:Number=4, blurX:Number=4, blurY:Number=4, alpha:Number=1, angle:Number=45, color:uint=0x000000, strength:Number=2, inner:Boolean=false, knockout:Boolean=false, hideObject:Boolean=false, quality:uint=2, remove:Boolean=false, index:int=-1, addFilter:Boolean=false) { | ||
| 40 | super(blurX, blurY, quality, remove, index, addFilter); | ||
| 41 | this.distance = distance; | ||
| 42 | this.alpha = alpha; | ||
| 43 | this.angle = angle; | ||
| 44 | this.color = color; | ||
| 45 | this.strength = strength; | ||
| 46 | this.inner = inner; | ||
| 47 | this.knockout = knockout; | ||
| 48 | this.hideObject = hideObject; | ||
| 49 | } | ||
| 50 | |||
| 51 | override protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 52 | super.initEnumerables(nulls, numbers.concat(["distance","alpha","angle","strength"])); | ||
| 53 | } | ||
| 54 | |||
| 55 | public static function create(vars:Object):DropShadowFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) | ||
| 56 | if (vars is DropShadowFilterVars) { | ||
| 57 | return vars as DropShadowFilterVars; | ||
| 58 | } | ||
| 59 | return new DropShadowFilterVars(vars.distance || 0, | ||
| 60 | vars.blurX || 0, | ||
| 61 | vars.blurY || 0, | ||
| 62 | vars.alpha || 0, | ||
| 63 | (vars.angle == null) ? 45 : vars.angle, | ||
| 64 | (vars.color == null) ? 0x000000 : vars.color, | ||
| 65 | (vars.strength == null) ? 2 : vars.strength, | ||
| 66 | Boolean(vars.inner), | ||
| 67 | Boolean(vars.knockout), | ||
| 68 | Boolean(vars.hideObject), | ||
| 69 | vars.quality || 2, | ||
| 70 | vars.remove || false, | ||
| 71 | (vars.index == null) ? -1 : vars.index, | ||
| 72 | vars.addFilter); | ||
| 73 | } | ||
| 74 | |||
| 75 | //---- GETTERS / SETTERS -------------------------------------------------------------------------------------------- | ||
| 76 | |||
| 77 | /** Color. **/ | ||
| 78 | public function get color():uint { | ||
| 79 | return uint(_values.color); | ||
| 80 | } | ||
| 81 | public function set color(value:uint):void { | ||
| 82 | setProp("color", value); | ||
| 83 | } | ||
| 84 | |||
| 85 | /** **/ | ||
| 86 | public function get inner():Boolean { | ||
| 87 | return Boolean(_values.inner); | ||
| 88 | } | ||
| 89 | public function set inner(value:Boolean):void { | ||
| 90 | setProp("inner", value); | ||
| 91 | } | ||
| 92 | |||
| 93 | /** **/ | ||
| 94 | public function get knockout():Boolean { | ||
| 95 | return Boolean(_values.knockout); | ||
| 96 | } | ||
| 97 | public function set knockout(value:Boolean):void { | ||
| 98 | setProp("knockout", value); | ||
| 99 | } | ||
| 100 | |||
| 101 | /** **/ | ||
| 102 | public function get hideObject():Boolean { | ||
| 103 | return Boolean(_values.hideObject); | ||
| 104 | } | ||
| 105 | public function set hideObject(value:Boolean):void { | ||
| 106 | setProp("hideObject", value); | ||
| 107 | } | ||
| 108 | |||
| 109 | } | ||
| 110 | |||
| 111 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.0 | ||
| 3 | * DATE: 8/1/2009 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.data { | ||
| 8 | import com.greensock.data.VarsCore; | ||
| 9 | /** | ||
| 10 | * This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 11 | * strict data typing and code hinting (in most code editors). See the documentation in | ||
| 12 | * the TweenLiteVars or TweenMaxVars for more information. | ||
| 13 | * | ||
| 14 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 15 | * | ||
| 16 | * @author Jack Doyle, jack@greensock.com | ||
| 17 | */ | ||
| 18 | dynamic public class FilterVars extends VarsCore { | ||
| 19 | |||
| 20 | public function FilterVars(remove:Boolean=false, index:int=-1, addFilter:Boolean=false) { | ||
| 21 | super(); | ||
| 22 | this.remove = remove; | ||
| 23 | if (index > -1) { | ||
| 24 | this.index = index; | ||
| 25 | } | ||
| 26 | this.addFilter = addFilter; | ||
| 27 | } | ||
| 28 | |||
| 29 | //---- GETTERS / SETTERS ----------------------------------------------------------------------------------------- | ||
| 30 | |||
| 31 | /** To remove the filter after the tween has completed, set remove to true. **/ | ||
| 32 | public function get remove():Boolean { | ||
| 33 | return Boolean(_values.remove); | ||
| 34 | } | ||
| 35 | public function set remove(value:Boolean):void { | ||
| 36 | setProp("remove", value); | ||
| 37 | } | ||
| 38 | |||
| 39 | /** To force TweenLite/Max to create a new filter even if there's a filter of the same kind already applied to a DisplayObject, set addFilter to true. **/ | ||
| 40 | public function get addFilter():Boolean { | ||
| 41 | return Boolean(_values.addFilter); | ||
| 42 | } | ||
| 43 | public function set addFilter(value:Boolean):void { | ||
| 44 | setProp("addFilter", value); | ||
| 45 | } | ||
| 46 | |||
| 47 | /** To define a particular index number in the target DisplayObject's filters Array for this filter, use index property. **/ | ||
| 48 | public function get index():int { | ||
| 49 | return int(_values.index); | ||
| 50 | } | ||
| 51 | public function set index(value:int):void { | ||
| 52 | setProp("index", value); | ||
| 53 | } | ||
| 54 | |||
| 55 | |||
| 56 | } | ||
| 57 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* | ||
| 2 | VERSION: 1.01 | ||
| 3 | DATE: 1/29/2009 | ||
| 4 | ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | DESCRIPTION: | ||
| 6 | This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 7 | strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in | ||
| 8 | the TweenLiteVars, or TweenMaxVars for more information. | ||
| 9 | |||
| 10 | USAGE: | ||
| 11 | |||
| 12 | Instead of TweenMax.to(my_mc, 1, {glowFilter:{blurX:10, blurY:10, color:0xFF0000}, onComplete:myFunction}), you could use this utility like: | ||
| 13 | |||
| 14 | var myVars:TweenMaxVars = new TweenMaxVars(); | ||
| 15 | myVars.glowFilter = new GlowFilterVars(10, 10); | ||
| 16 | myVars.onComplete = myFunction; | ||
| 17 | TweenMax.to(my_mc, 1, myVars); | ||
| 18 | |||
| 19 | |||
| 20 | NOTES: | ||
| 21 | - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel | ||
| 22 | free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. | ||
| 23 | - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly | ||
| 24 | data typed) syntax, like TweenMax.to(my_mc, 1, {glowFilter:{blurX:"-5", blurY:"3"}}); | ||
| 25 | |||
| 26 | AUTHOR: Jack Doyle, jack@greensock.com | ||
| 27 | Copyright 2010, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 28 | */ | ||
| 29 | |||
| 30 | |||
| 31 | package com.greensock.data { | ||
| 32 | |||
| 33 | public class GlowFilterVars extends BlurFilterVars { | ||
| 34 | public var alpha:Number; | ||
| 35 | public var strength:Number; | ||
| 36 | |||
| 37 | public function GlowFilterVars(blurX:Number=10, blurY:Number=10, color:uint=0xFFFFFF, alpha:Number=1, strength:Number=2, inner:Boolean=false, knockout:Boolean=false, quality:uint=2, remove:Boolean=false, index:int=-1, addFilter:Boolean=false) { | ||
| 38 | super(blurX, blurY, quality, remove, index, addFilter); | ||
| 39 | this.color = color; | ||
| 40 | this.alpha = alpha; | ||
| 41 | this.strength = strength; | ||
| 42 | this.inner = inner; | ||
| 43 | this.knockout = knockout; | ||
| 44 | } | ||
| 45 | |||
| 46 | override protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 47 | super.initEnumerables(nulls, numbers.concat(["alpha","strength"])); | ||
| 48 | } | ||
| 49 | |||
| 50 | public static function create(vars:Object):GlowFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) | ||
| 51 | if (vars is GlowFilterVars) { | ||
| 52 | return vars as GlowFilterVars; | ||
| 53 | } | ||
| 54 | return new GlowFilterVars(vars.blurX || 0, | ||
| 55 | vars.blurY || 0, | ||
| 56 | (vars.color == null) ? 0x000000 : vars.color, | ||
| 57 | vars.alpha || 0, | ||
| 58 | (vars.strength == null) ? 2 : vars.strength, | ||
| 59 | Boolean(vars.inner), | ||
| 60 | Boolean(vars.knockout), | ||
| 61 | vars.quality || 2, | ||
| 62 | vars.remove || false, | ||
| 63 | (vars.index == null) ? -1 : vars.index, | ||
| 64 | vars.addFilter || false); | ||
| 65 | } | ||
| 66 | |||
| 67 | //---- GETTERS / SETTERS ------------------------------------------------------------------------------------- | ||
| 68 | |||
| 69 | /** Color. **/ | ||
| 70 | public function get color():uint { | ||
| 71 | return uint(_values.color); | ||
| 72 | } | ||
| 73 | public function set color(value:uint):void { | ||
| 74 | setProp("color", value); | ||
| 75 | } | ||
| 76 | |||
| 77 | /** **/ | ||
| 78 | public function get inner():Boolean { | ||
| 79 | return Boolean(_values.inner); | ||
| 80 | } | ||
| 81 | public function set inner(value:Boolean):void { | ||
| 82 | setProp("inner", value); | ||
| 83 | } | ||
| 84 | |||
| 85 | /** **/ | ||
| 86 | public function get knockout():Boolean { | ||
| 87 | return Boolean(_values.knockout); | ||
| 88 | } | ||
| 89 | public function set knockout(value:Boolean):void { | ||
| 90 | setProp("knockout", value); | ||
| 91 | } | ||
| 92 | |||
| 93 | |||
| 94 | } | ||
| 95 | |||
| 96 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* | ||
| 2 | VERSION: 1.0 | ||
| 3 | DATE: 1/29/2009 | ||
| 4 | ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | DESCRIPTION: | ||
| 6 | This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 7 | strict data typing and code hinting (in most code editors) for transformAroundPoint tweens. See the documentation in | ||
| 8 | the TweenLiteVars or TweenMaxVars for more information. | ||
| 9 | |||
| 10 | USAGE: | ||
| 11 | |||
| 12 | Instead of TweenMax.to(my_mc, 1, {transformAroundCenter:{scaleX:2, scaleY:1.5, rotation:30}}, onComplete:myFunction}), you could use this utility like: | ||
| 13 | |||
| 14 | var myVars:TweenMaxVars = new TweenMaxVars(); | ||
| 15 | myVars.transformAroundPoint = new TransformAroundCenterVars(2, 1.5, 30); | ||
| 16 | myVars.onComplete = myFunction; | ||
| 17 | TweenMax.to(my_mc, 1, myVars); | ||
| 18 | |||
| 19 | |||
| 20 | NOTES: | ||
| 21 | - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel | ||
| 22 | free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. | ||
| 23 | - You cannot define relative tween values with this utility. | ||
| 24 | |||
| 25 | AUTHOR: Jack Doyle, jack@greensock.com | ||
| 26 | Copyright 2010, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 27 | */ | ||
| 28 | |||
| 29 | |||
| 30 | package com.greensock.data { | ||
| 31 | import flash.geom.Point; | ||
| 32 | |||
| 33 | public class TransformAroundCenterVars extends TransformAroundPointVars { | ||
| 34 | |||
| 35 | public function TransformAroundCenterVars(scaleX:Number=NaN, scaleY:Number=NaN, rotation:Number=NaN, width:Number=NaN, height:Number=NaN, shortRotation:Object=null, x:Number=NaN, y:Number=NaN) { | ||
| 36 | super(null, scaleX, scaleY, rotation, width, height, shortRotation, x, y); | ||
| 37 | } | ||
| 38 | |||
| 39 | public static function create(vars:Object):TransformAroundCenterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) | ||
| 40 | if (vars is TransformAroundCenterVars) { | ||
| 41 | return vars as TransformAroundCenterVars; | ||
| 42 | } | ||
| 43 | return new TransformAroundCenterVars(vars.scaleX, | ||
| 44 | vars.scaleY, | ||
| 45 | vars.rotation, | ||
| 46 | vars.width, | ||
| 47 | vars.height, | ||
| 48 | vars.shortRotation, | ||
| 49 | vars.x, | ||
| 50 | vars.y); | ||
| 51 | } | ||
| 52 | |||
| 53 | } | ||
| 54 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* | ||
| 2 | VERSION: 1.0 | ||
| 3 | DATE: 1/29/2009 | ||
| 4 | ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | DESCRIPTION: | ||
| 6 | This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant | ||
| 7 | strict data typing and code hinting (in most code editors) for transformAroundPoint tweens. See the documentation in | ||
| 8 | the TweenLiteVars or TweenMaxVars for more information. | ||
| 9 | |||
| 10 | USAGE: | ||
| 11 | |||
| 12 | Instead of TweenMax.to(my_mc, 1, {transformAroundPoint:{point:new Point(100, 50), scaleX:2, scaleY:1.5, rotation:30}}, onComplete:myFunction}), you could use this utility like: | ||
| 13 | |||
| 14 | var myVars:TweenMaxVars = new TweenMaxVars(); | ||
| 15 | myVars.transformAroundPoint = new TransformAroundPointVars(new Point(100, 50), 2, 1.5, 30); | ||
| 16 | myVars.onComplete = myFunction; | ||
| 17 | TweenMax.to(my_mc, 1, myVars); | ||
| 18 | |||
| 19 | |||
| 20 | NOTES: | ||
| 21 | - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel | ||
| 22 | free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. | ||
| 23 | - You cannot define relative tween values with this utility. | ||
| 24 | |||
| 25 | AUTHOR: Jack Doyle, jack@greensock.com | ||
| 26 | Copyright 2010, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 27 | */ | ||
| 28 | |||
| 29 | |||
| 30 | package com.greensock.data { | ||
| 31 | import flash.geom.Point; | ||
| 32 | |||
| 33 | public class TransformAroundPointVars extends VarsCore { | ||
| 34 | public var point:Point; | ||
| 35 | public var scaleX:Number; | ||
| 36 | public var scaleY:Number; | ||
| 37 | public var scale:Number; | ||
| 38 | public var rotation:Number; | ||
| 39 | public var width:Number; | ||
| 40 | public var height:Number; | ||
| 41 | public var shortRotation:Object; | ||
| 42 | public var x:Number; | ||
| 43 | public var y:Number; | ||
| 44 | |||
| 45 | public function TransformAroundPointVars(point:Point=null, scaleX:Number=NaN, scaleY:Number=NaN, rotation:Number=NaN, width:Number=NaN, height:Number=NaN, shortRotation:Object=null, x:Number=NaN, y:Number=NaN) { | ||
| 46 | super(); | ||
| 47 | if (point != null) { | ||
| 48 | this.point = point; | ||
| 49 | } | ||
| 50 | if (scaleX || scaleX == 0) { //faster than !isNaN()) | ||
| 51 | this.scaleX = scaleX; | ||
| 52 | } | ||
| 53 | if (scaleY || scaleY == 0) { | ||
| 54 | this.scaleY = scaleY; | ||
| 55 | } | ||
| 56 | if (rotation || rotation == 0) { | ||
| 57 | this.rotation = rotation; | ||
| 58 | } | ||
| 59 | if (width || width == 0) { | ||
| 60 | this.width = width; | ||
| 61 | } | ||
| 62 | if (height || height == 0) { | ||
| 63 | this.height = height; | ||
| 64 | } | ||
| 65 | if (shortRotation != null) { | ||
| 66 | this.shortRotation = shortRotation; | ||
| 67 | } | ||
| 68 | if (x || x == 0) { | ||
| 69 | this.x = x; | ||
| 70 | } | ||
| 71 | if (y || y == 0) { | ||
| 72 | this.y = y; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | override protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 77 | super.initEnumerables(nulls.concat(["point","shortRotation"]), numbers.concat(["scaleX","scaleY","scale","rotation","width","height","x","y"])); | ||
| 78 | } | ||
| 79 | |||
| 80 | public static function create(vars:Object):TransformAroundPointVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) | ||
| 81 | if (vars is TransformAroundPointVars) { | ||
| 82 | return vars as TransformAroundPointVars; | ||
| 83 | } | ||
| 84 | return new TransformAroundPointVars(vars.point, | ||
| 85 | vars.scaleX, | ||
| 86 | vars.scaleY, | ||
| 87 | vars.rotation, | ||
| 88 | vars.width, | ||
| 89 | vars.height, | ||
| 90 | vars.shortRotation, | ||
| 91 | vars.x, | ||
| 92 | vars.y); | ||
| 93 | } | ||
| 94 | |||
| 95 | |||
| 96 | |||
| 97 | } | ||
| 98 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 4.02 | ||
| 3 | * DATE: 2010-03-06 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | |||
| 8 | package com.greensock.data { | ||
| 9 | import com.greensock.TweenLite; | ||
| 10 | /** | ||
| 11 | * There are 2 primary benefits of using a TweenLiteVars instance to define your TweenLite variables: | ||
| 12 | * <ol> | ||
| 13 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in TweenLite</li> | ||
| 14 | * <li> It allows you to code using strict datatyping (although it doesn't force you to).</li> | ||
| 15 | * </ol> | ||
| 16 | * | ||
| 17 | * <b>USAGE:</b><br /><br /> | ||
| 18 | * | ||
| 19 | * Instead of <code>TweenLite.to(mc, 1, {x:300, tint:0xFF0000, onComplete:myFunction})</code>, you could use this utility like:<br /><br /><code> | ||
| 20 | * | ||
| 21 | * var myVars:TweenLiteVars = new TweenLiteVars();<br /> | ||
| 22 | * myVars.addProp("x", 300); // use addProp() to add any property that doesn't already exist in the TweenLiteVars instance.<br /> | ||
| 23 | * myVars.tint = 0xFF0000;<br /> | ||
| 24 | * myVars.onComplete = myFunction;<br /> | ||
| 25 | * TweenLite.to(mc, 1, myVars);<br /><br /></code> | ||
| 26 | * | ||
| 27 | * | ||
| 28 | * <b>NOTES:</b><br /> | ||
| 29 | * <ul> | ||
| 30 | * <li> This class adds about 13 Kb to your published SWF (including all dependencies).</li> | ||
| 31 | * <li> This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite class, feel | ||
| 32 | * free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict datatyping.</li> | ||
| 33 | * <li> You can reuse a single TweenLiteVars Object for multiple tweens if you want, but be aware that there are a few | ||
| 34 | * properties that must be handled in a special way, and once you set them, you cannot remove them. Those properties | ||
| 35 | * are: frame, visible, tint, and volume. If you are altering these values, it might be better to avoid reusing a TweenLiteVars</li> | ||
| 36 | * Object. | ||
| 37 | * </ul> | ||
| 38 | * | ||
| 39 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 40 | * | ||
| 41 | * @author Jack Doyle, jack@greensock.com | ||
| 42 | */ | ||
| 43 | dynamic public class TweenLiteVars extends VarsCore { | ||
| 44 | /** @private **/ | ||
| 45 | protected static var _subVars:Object = {blurFilter:BlurFilterVars, colorMatrixFilter:ColorMatrixFilterVars, bevelFilter:BevelFilterVars, glowFilter:GlowFilterVars, transformAroundPoint:TransformAroundPointVars, transformAroundCenter:TransformAroundCenterVars, colorTransform:ColorTransformVars}; | ||
| 46 | |||
| 47 | /** Any data that you'd like associated with your tween. **/ | ||
| 48 | public var data:*; | ||
| 49 | /** The number of seconds (or frames for frames-based tweens) to delay before the tween begins. **/ | ||
| 50 | public var delay:Number; | ||
| 51 | /** An easing function (i.e. fl.motion.easing.Elastic.easeOut) The default is Regular.easeOut. **/ | ||
| 52 | public var ease:Function; | ||
| 53 | /** An Array of extra parameter values to feed the easing equation (beyond the standard 4). This can be useful with easing equations like Elastic that accept extra parameters like the amplitude and period. Most easing equations, however, don't require extra parameters so you won't need to pass in any easeParams. **/ | ||
| 54 | public var easeParams:Array; | ||
| 55 | /** A function that should be called just before the tween inits (renders for the first time). | ||
| 56 | * Since onInit runs before the start/end values are recorded internally, it is a good place to run | ||
| 57 | * code that affects the target's initial position or other tween-related properties. onStart, by | ||
| 58 | * contrast, runs AFTER the tween inits and the start/end values are recorded internally. onStart | ||
| 59 | * is called every time the tween begins which can happen more than once if the tween is restarted | ||
| 60 | * multiple times. **/ | ||
| 61 | public var onInit:Function; | ||
| 62 | /** An Array of parameters to pass the onInit function. **/ | ||
| 63 | public var onInitParams:Array; | ||
| 64 | /** A function that should be called when the tween begins (when its currentTime is at 0 and changes to some other value which can happen more than once if the tween is restarted multiple times). **/ | ||
| 65 | public var onStart:Function; | ||
| 66 | /** An Array of parameters to pass the onStart function. **/ | ||
| 67 | public var onStartParams:Array; | ||
| 68 | /** A function to call whenever the tweening values are updated (on every frame during the time the tween is active). **/ | ||
| 69 | public var onUpdate:Function; | ||
| 70 | /** An Array of parameters to pass the onUpdate function **/ | ||
| 71 | public var onUpdateParams:Array; | ||
| 72 | /** A function to call when the tween has completed. **/ | ||
| 73 | public var onComplete:Function; | ||
| 74 | /** An Array of parameters to pass the onComplete function **/ | ||
| 75 | public var onCompleteParams:Array; | ||
| 76 | /** Allows you to associate a function with a property so that every time the tween is updated, it calls that function to get the end value for the associated property. You could, for example, tween an object's x/y coordinates to wherever the mouse is. **/ | ||
| 77 | public var dynamicProps:Object; | ||
| 78 | /** Tweens the scrollRect property of any DisplayObject; you can define any of the following properties in the object: left, right, top, bottom, x, y, width, height. **/ | ||
| 79 | public var scrollRect:Object; | ||
| 80 | |||
| 81 | /** Same as changing the "alpha" property but with the additional feature of toggling the "visible" property to false when alpha is 0. **/ | ||
| 82 | public var autoAlpha:Number; | ||
| 83 | /** An Array containing numeric end values of the target Array. Keep in mind that the target of the tween must be an Array with at least the same length as the endArray. **/ | ||
| 84 | public var endArray:Array; | ||
| 85 | /** Tweens a MovieClip to a particular frame. **/ | ||
| 86 | public var frameLabel:String; | ||
| 87 | /** Changes the volume of any object that has a soundTransform property (MovieClip, SoundChannel, NetStream, etc.) **/ | ||
| 88 | public var volume:Number; | ||
| 89 | /** Applies a BevelFilter tween (use the BevelFilterVars class to define the values). **/ | ||
| 90 | public var bevelFilter:BevelFilterVars; | ||
| 91 | /** Array of Objects, one for each "control point" (see documentation on Flash's curveTo() drawing method for more about how control points work). In this example, let's say the control point would be at x/y coordinates 250,50. Just make sure your my_mc is at coordinates 0,0 and then do: TweenLite.to(my_mc, 3, {bezier:[{x:250, y:50}, {x:500, y:0}]}); **/ | ||
| 92 | public var bezier:Array; | ||
| 93 | /** Identical to bezier except that instead of passing Bezier control point values, you pass values through which the Bezier values should move. This can be more intuitive than using control points. **/ | ||
| 94 | public var bezierThrough:Array; | ||
| 95 | /** Applies a BlurFilter tween (use the BlurFilterVars class to define the values). **/ | ||
| 96 | public var blurFilter:BlurFilterVars; | ||
| 97 | /** Applies a ColorMatrixFilter tween (use the ColorMatrixFilterVars class to define the values). **/ | ||
| 98 | public var colorMatrixFilter:ColorMatrixFilterVars; | ||
| 99 | /** Applies a DropShadowFilter tween (use the DropShadowFilterVars class to define the values). **/ | ||
| 100 | public var dropShadowFilter:DropShadowFilterVars; | ||
| 101 | /** Applies a GlowFilter tween (use the GlowFilterVars class to define the values). **/ | ||
| 102 | public var glowFilter:GlowFilterVars; | ||
| 103 | /** Although hex colors are technically numbers, if you try to tween them conventionally, you'll notice that they don't tween smoothly. To tween them properly, the red, green, and blue components must be extracted and tweened independently. TweenMax makes it easy. To tween a property of your object that's a hex color to another hex color, use this special hexColors property of TweenMax. It must be an OBJECT with properties named the same as your object's hex color properties. For example, if your my_obj object has a "myHexColor" property that you'd like to tween to red (0xFF0000) over the course of 2 seconds, do: TweenMax.to(my_obj, 2, {hexColors:{myHexColor:0xFF0000}}); You can pass in any number of hexColor properties. **/ | ||
| 104 | public var hexColors:Object; | ||
| 105 | /** | ||
| 106 | * A common effect that designers/developers want is for a MovieClip/Sprite to orient itself in the direction of a Bezier path (alter its rotation). orientToBezier makes it easy. In order to alter a rotation property accurately, TweenLite/Max needs 4 pieces of information: | ||
| 107 | * <ol> | ||
| 108 | * <li>Position property 1 (typically "x")</li> | ||
| 109 | * <li>Position property 2 (typically "y")</li> | ||
| 110 | * <li>Rotational property (typically "rotation")</li> | ||
| 111 | * <li>Number of degrees to add (optional - makes it easy to orient your MovieClip/Sprite properly)</li> | ||
| 112 | * <ol> | ||
| 113 | * The orientToBezier property should be an Array containing one Array for each set of these values. For maximum flexibility, you can pass in any number of Arrays inside the container Array, one for each rotational property. This can be convenient when working in 3D because you can rotate on multiple axis. If you're doing a standard 2D x/y tween on a bezier, you can simply pass in a boolean value of true and TweenMax will use a typical setup, [["x", "y", "rotation", 0]]. Hint: Don't forget the container Array (notice the double outer brackets) | ||
| 114 | */ | ||
| 115 | public var orientToBezier:Array; | ||
| 116 | /** An object with properties that correspond to the quaternion properties of the target object. For example, if your my3DObject has "orientation" and "childOrientation" properties that contain quaternions, and you'd like to tween them both, you'd do: {orientation:myTargetQuaternion1, childOrientation:myTargetQuaternion2}. Quaternions must have the following properties: x, y, z, and w. **/ | ||
| 117 | public var quaternions:Object; | ||
| 118 | /** An object containing a "width" and/or "height" property which will be tweened over time and applied using setSize() on every frame during the course of the tween. **/ | ||
| 119 | public var setSize:Object; | ||
| 120 | /** To tween any rotation property (even multiple properties) of the target object in the shortest direction, use shortRotation. For example, if myObject.rotation is currently 170 degrees and you want to tween it to -170 degrees, a normal rotation tween would travel a total of 340 degrees in the counter-clockwise direction, but if you use shortRotation, it would travel 20 degrees in the clockwise direction instead. Pass in an object in with properties that correspond to the rotation values of the target, like {rotation:-170} or {rotationX:-170, rotationY:50} **/ | ||
| 121 | public var shortRotation:Object; | ||
| 122 | /** Applies a transformAroundPoint tween (use the TransformAroundPointVars class to define the values). **/ | ||
| 123 | public var transformAroundPoint:TransformAroundPointVars; | ||
| 124 | /** Applies a transformAroundCenter tween (use the TransformAroundCenterVars class to define the values). **/ | ||
| 125 | public var transformAroundCenter:TransformAroundCenterVars; | ||
| 126 | /** Applies a ColorTransform tween (use the ColorTransformVars class to define the values). **/ | ||
| 127 | public var colorTransform:ColorTransformVars; | ||
| 128 | /** Applies a motionBlur tween. **/ | ||
| 129 | public var motionBlur:Object; | ||
| 130 | |||
| 131 | |||
| 132 | /** | ||
| 133 | * Constructor | ||
| 134 | * @param vars An Object containing properties that correspond to the properties you'd like to add to this TweenLiteVars Object. For example, TweenLiteVars({x:300, onComplete:myFunction}) | ||
| 135 | */ | ||
| 136 | public function TweenLiteVars(vars:Object=null) { | ||
| 137 | super(); | ||
| 138 | initEnumerables(["data","ease","easeParams","onInit","onInitParams","onStart","onStartParams","onUpdate","onUpdateParams","onComplete", | ||
| 139 | "onCompleteParams","endArray","frameLabel","bevelFilter","bezier","bezierThrough", | ||
| 140 | "blurFilter","colorMatrixFilter","dropShadowFilter","glowFilter","hexColors","orientToBezier","quaternions", | ||
| 141 | "setSize","shortRotation","transformAroundPoint","transformAroundCenter","colorTransform","motionBlur","dynamicProps"], | ||
| 142 | ["autoAlpha","delay","volume"]); | ||
| 143 | if (vars != null) { | ||
| 144 | for (var p:String in vars) { | ||
| 145 | if (p in _subVars) { | ||
| 146 | _subVars[p].create(vars[p]); | ||
| 147 | } else { | ||
| 148 | this[p] = vars[p]; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | } | ||
| 152 | if (TweenLite.version < 11) { | ||
| 153 | trace("TweenLiteVars error! Please update your TweenLite class or try deleting your ASO files. TweenLiteVars requires a more recent version. Download updates at http://www.TweenLite.com."); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | /** | ||
| 158 | * Adds a dynamic property for tweening and allows you to set whether the end value is relative or not | ||
| 159 | * | ||
| 160 | * @param name Property name | ||
| 161 | * @param value Numeric end value (or beginning value for from() calls) | ||
| 162 | * @param relative If true, the value will be relative to the target's current value. For example, if my_mc.x is currently 300 and you do addProp("x", 200, true), the end value will be 500. | ||
| 163 | */ | ||
| 164 | public function addProp(name:String, value:Number, relative:Boolean=false):void { | ||
| 165 | this[name] = (relative) ? String(value) : value; | ||
| 166 | } | ||
| 167 | |||
| 168 | /** Clones the TweenLiteVars object. **/ | ||
| 169 | public function clone():TweenLiteVars { | ||
| 170 | return this.copyPropsTo(new TweenLiteVars()) as TweenLiteVars; | ||
| 171 | } | ||
| 172 | |||
| 173 | |||
| 174 | //---- GETTERS / SETTERS ------------------------------------------------------------------------------------------------------------- | ||
| 175 | |||
| 176 | /** To remove the tint from a DisplayObject, set removeTint to true. **/ | ||
| 177 | public function get removeTint():Boolean { | ||
| 178 | return Boolean(_values.removeTint); | ||
| 179 | } | ||
| 180 | public function set removeTint(value:Boolean):void { | ||
| 181 | setProp("removeTint", value); | ||
| 182 | } | ||
| 183 | |||
| 184 | /** To set a DisplayObject's "visible" property at the end of the tween, use this special property. **/ | ||
| 185 | public function get visible():Boolean { | ||
| 186 | return Boolean(_values.visible); | ||
| 187 | } | ||
| 188 | public function set visible(value:Boolean):void { | ||
| 189 | setProp("visible", value); | ||
| 190 | } | ||
| 191 | |||
| 192 | /** Tweens a MovieClip to a particular frame. **/ | ||
| 193 | public function get frame():int { | ||
| 194 | return int(_values.frame); | ||
| 195 | } | ||
| 196 | public function set frame(value:int):void { | ||
| 197 | setProp("frame", value); | ||
| 198 | } | ||
| 199 | |||
| 200 | /** To change a DisplayObject's tint, set this to the hex value of the color you'd like the DisplayObject to end up at(or begin at if you're using TweenLite.from()). An example hex value would be 0xFF0000. If you'd like to remove the tint from a DisplayObject, use the removeTint special property. **/ | ||
| 201 | public function get tint():uint { | ||
| 202 | return uint(_values.tint); | ||
| 203 | } | ||
| 204 | public function set tint(value:uint):void { | ||
| 205 | setProp("tint", value); | ||
| 206 | } | ||
| 207 | |||
| 208 | /** Normally, zero-duration tweens render immediately and all other tweens begin rendering on the very next frame after they are instantiated, but immediateRender allows you to override that behavior if you prefer. For example, if you're inserting a zero-duration tween into a timeline, you should set immediateRender:false so that it doesn't render immediately. **/ | ||
| 209 | public function get immediateRender():Boolean { | ||
| 210 | return Boolean(_values.immediateRender); | ||
| 211 | } | ||
| 212 | public function set immediateRender(value:Boolean):void { | ||
| 213 | setProp("immediateRender", value); | ||
| 214 | } | ||
| 215 | |||
| 216 | /** When true, the tween will flip the start and end values which is exactly what TweenLite.from() does. **/ | ||
| 217 | public function get runBackwards():Boolean { | ||
| 218 | return Boolean(_values.runBackwards); | ||
| 219 | } | ||
| 220 | public function set runBackwards(value:Boolean):void { | ||
| 221 | setProp("runBackwards", value); | ||
| 222 | } | ||
| 223 | |||
| 224 | /** If useFrames is set to true, the tweens's timing mode will be based on frames. Otherwise, it will be based on seconds/time. NOTE: a tween's timing mode is always determined by its parent timeline. **/ | ||
| 225 | public function get useFrames():Boolean { | ||
| 226 | return Boolean(_values.useFrames); | ||
| 227 | } | ||
| 228 | public function set useFrames(value:Boolean):void { | ||
| 229 | setProp("useFrames", value); | ||
| 230 | } | ||
| 231 | |||
| 232 | /** NONE = 0, ALL_IMMEDIATE = 1, AUTO = 2, CONCURRENT = 3, ALL_ONSTART = 4, PREEXISTING = 5 (2 through 5 are only available with the optional OverwriteManager add-on class which must be initted once for TweenLite, like OverwriteManager.init(). TweenMax, TimelineLite, and TimelineMax automatically init OverwriteManager. **/ | ||
| 233 | public function get overwrite():int { | ||
| 234 | if ("overwrite" in _values) { | ||
| 235 | return int(_values.overwrite); | ||
| 236 | } | ||
| 237 | return -1; | ||
| 238 | } | ||
| 239 | public function set overwrite(value:int):void { | ||
| 240 | setProp("overwrite", value); | ||
| 241 | } | ||
| 242 | |||
| 243 | } | ||
| 244 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 4.0 | ||
| 3 | * DATE: 8/3/2009 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.data { | ||
| 8 | import com.greensock.data.TweenLiteVars; | ||
| 9 | /** | ||
| 10 | * There are 2 primary benefits of using this utility to define your TweenMax variables: | ||
| 11 | * <ol> | ||
| 12 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in TweenMax</li> | ||
| 13 | * <li> It allows you to code using strict datatyping (although it doesn't force you to). </li> | ||
| 14 | * </ol> | ||
| 15 | * | ||
| 16 | * <b>USAGE:</b><br /><br /> | ||
| 17 | * | ||
| 18 | * Instead of TweenMax.to(my_mc, 1, {x:300, tint:0xFF0000, onComplete:myFunction}), you could use this utility like:<br /><br /><code> | ||
| 19 | * | ||
| 20 | * var myVars:TweenMaxVars = new TweenMaxVars();<br /> | ||
| 21 | * myVars.addProp("x", 300); // use addProp() to add any property that doesn't already exist in the TweenMaxVars instance.<br /> | ||
| 22 | * myVars.tint = 0xFF0000;<br /> | ||
| 23 | * myVars.onComplete = myFunction;<br /> | ||
| 24 | * TweenMax.to(my_mc, 1, myVars);<br /><br /></code> | ||
| 25 | * | ||
| 26 | * | ||
| 27 | * <b>NOTES:</b> | ||
| 28 | * <ul> | ||
| 29 | * <li> This class adds about 14 Kb to your published SWF.</li> | ||
| 30 | * <li> This utility is completely optional. If you prefer the shorter synatax in the regular TweenMax class, feel | ||
| 31 | * free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict datatyping.</li> | ||
| 32 | * <li> You may add custom properties to this class if you want, but in order to expose them to TweenMax, make sure | ||
| 33 | * you also add a getter and a setter that adds the property to the _exposedVars Object.</li> | ||
| 34 | * <li> You can reuse a single TweenMaxVars Object for multiple tweens if you want, but be aware that there are a few | ||
| 35 | * properties that must be handled in a special way, and once you set them, you cannot remove them. Those properties | ||
| 36 | * are: frame, visible, tint, and volume. If you are altering these values, it might be better to avoid reusing a TweenMaxVars | ||
| 37 | * Object.</li> | ||
| 38 | * </ul> | ||
| 39 | * | ||
| 40 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 41 | * | ||
| 42 | * @author Jack Doyle, jack@greensock.com | ||
| 43 | */ | ||
| 44 | dynamic public class TweenMaxVars extends TweenLiteVars { | ||
| 45 | /** A function to which the TweenMax instance should dispatch a TweenEvent when it begins. This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.START, myFunction); **/ | ||
| 46 | public var onStartListener:Function; | ||
| 47 | /** A function to which the TweenMax instance should dispatch a TweenEvent every time it updates values. This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.UPDATE, myFunction); **/ | ||
| 48 | public var onUpdateListener:Function; | ||
| 49 | /** A function to which the TweenMax instance should dispatch a TweenEvent when it completes. This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.COMPLETE, myFunction); **/ | ||
| 50 | public var onCompleteListener:Function; | ||
| 51 | /** A function that should be called when the tween has reached its starting point again after having been reversed **/ | ||
| 52 | public var onReverseComplete : Function; | ||
| 53 | /** An Array of parameters to pass the onReverseComplete functions **/ | ||
| 54 | public var onReverseCompleteParams : Array; | ||
| 55 | /** A function that should be called every time the tween repeats **/ | ||
| 56 | public var onRepeat : Function; | ||
| 57 | /** An Array of parameters to pass the onRepeat function **/ | ||
| 58 | public var onRepeatParams : Array; | ||
| 59 | /** Amount of time in seconds (or frames for frames-based tween) between repeats. **/ | ||
| 60 | public var repeatDelay:Number; | ||
| 61 | /** Allows you to define the starting values for each property. Typically, TweenMax uses the current value (whatever it happens to be at the time the tween begins) as the start value, but startAt allows you to override that behavior. Simply pass an object in with whatever properties you'd liketo set just before the tween begins. For example, if mc.x is currently 100, and you'd like to tween it from 0 to 500, do TweenMax.to(mc, 2, {x:500, startAt:{x:0}}); **/ | ||
| 62 | public var startAt:TweenLiteVars; | ||
| 63 | /** An Array of the names of properties that should be rounded to the nearest integer when tweening **/ | ||
| 64 | public var roundProps:Array; | ||
| 65 | |||
| 66 | /** | ||
| 67 | * @param vars An Object containing properties that correspond to the properties you'd like to add to this TweenMaxVars Object. For example, TweenMaxVars({blurFilter:{blurX:10, blurY:20}, onComplete:myFunction}) | ||
| 68 | */ | ||
| 69 | public function TweenMaxVars(vars:Object=null) { | ||
| 70 | super(vars); | ||
| 71 | } | ||
| 72 | |||
| 73 | /** @private **/ | ||
| 74 | override protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 75 | super.initEnumerables(nulls.concat(["onStartListener","onUpdateListener","onReverseCompleteListener","onReverseCompleteParams", | ||
| 76 | "onRepeat","onRepeatParams","startAt","roundProps"]), | ||
| 77 | numbers.concat(["repeatDelay"])); | ||
| 78 | } | ||
| 79 | |||
| 80 | /** Clones the TweenMaxVars object. **/ | ||
| 81 | override public function clone():TweenLiteVars { | ||
| 82 | return this.copyPropsTo(new TweenMaxVars()) as TweenMaxVars; | ||
| 83 | } | ||
| 84 | |||
| 85 | |||
| 86 | //---- GETTERS / SETTERS --------------------------------------------------------------------------------------------- | ||
| 87 | |||
| 88 | /** Works in conjunction with the repeat property, determining the behavior of each cycle. When yoyo is true, the tween will go back and forth, appearing to reverse every other cycle (this has no affect on the "reversed" property though). **/ | ||
| 89 | public function get yoyo():Boolean { | ||
| 90 | return Boolean(_values.yoyo); | ||
| 91 | } | ||
| 92 | public function set yoyo(value:Boolean):void { | ||
| 93 | setProp("yoyo", value); | ||
| 94 | } | ||
| 95 | |||
| 96 | /** If true, the tween will be paused initially. **/ | ||
| 97 | public function get paused():Boolean { | ||
| 98 | return Boolean(_values.paused); | ||
| 99 | } | ||
| 100 | public function set paused(value:Boolean):void { | ||
| 101 | setProp("paused", value); | ||
| 102 | } | ||
| 103 | |||
| 104 | /** If true, the tween will be reversed initially. This does not swap the starting/ending values in the tween - it literally changes its orientation/direction. Imagine the playhead moving backwards instead of forwards. **/ | ||
| 105 | public function get reversed():Boolean { | ||
| 106 | return Boolean(_values.reversed); | ||
| 107 | } | ||
| 108 | public function set reversed(value:Boolean):void { | ||
| 109 | setProp("reversed", value); | ||
| 110 | } | ||
| 111 | |||
| 112 | /** Number of times that the tween should repeat (to repeat indefinitely, use -1). **/ | ||
| 113 | public function get repeat():int { | ||
| 114 | return int(_values.repeat); | ||
| 115 | } | ||
| 116 | public function set repeat(value:int):void { | ||
| 117 | setProp("repeat", value); | ||
| 118 | } | ||
| 119 | |||
| 120 | |||
| 121 | |||
| 122 | } | ||
| 123 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.01 | ||
| 3 | * DATE: 9/23/2009 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenLite.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.data { | ||
| 8 | import flash.utils.Proxy; | ||
| 9 | import flash.utils.flash_proxy; | ||
| 10 | /** | ||
| 11 | * VarsCore provides a way to make an object's non-dynamic properties enumerable (only if/when the property is | ||
| 12 | * set to a non-default value) which is necessary for many of the vars objects in the GreenSock tweening | ||
| 13 | * platform (TweenLiteVars, TweenMaxVars, etc.). There is no reason to use VarsCore directly, but rather use | ||
| 14 | * a subclass like TweenLiteVars to enable strict data typing and code hinting in modern apps like Flex Builder, FDT, etc. | ||
| 15 | * | ||
| 16 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 17 | * | ||
| 18 | * @author Jack Doyle, jack@greensock.com | ||
| 19 | */ | ||
| 20 | dynamic public class VarsCore extends Proxy { | ||
| 21 | /** @private (for backwards compatibility) **/ | ||
| 22 | public const isTV:Boolean = true; | ||
| 23 | /** @private faster to use an already-created empty Array rather than keep re-creating them. **/ | ||
| 24 | protected static const _empty:Array = []; | ||
| 25 | |||
| 26 | /** @private **/ | ||
| 27 | protected var _numbers:Object = {}; | ||
| 28 | /** @private **/ | ||
| 29 | protected var _props:Array; | ||
| 30 | /** @private **/ | ||
| 31 | protected var _values:Object = {}; | ||
| 32 | |||
| 33 | /** Constructor **/ | ||
| 34 | public function VarsCore() { | ||
| 35 | initEnumerables(_empty, _empty); | ||
| 36 | } | ||
| 37 | |||
| 38 | /** @private **/ | ||
| 39 | protected function initEnumerables(nulls:Array, numbers:Array):void { | ||
| 40 | _props = nulls.concat(numbers); | ||
| 41 | var i:int = numbers.length; | ||
| 42 | while (i-- > 0) { | ||
| 43 | _numbers[numbers[i]] = true; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | /** @private **/ | ||
| 48 | flash_proxy override function getProperty(prop:*):* { | ||
| 49 | return _values[prop]; | ||
| 50 | } | ||
| 51 | |||
| 52 | /** @private **/ | ||
| 53 | flash_proxy override function setProperty(prop:*, value:*):void { | ||
| 54 | setProp(String(prop), value); | ||
| 55 | } | ||
| 56 | |||
| 57 | flash_proxy override function hasProperty(name:*):Boolean { | ||
| 58 | return name in _values; | ||
| 59 | } | ||
| 60 | |||
| 61 | |||
| 62 | /** @private **/ | ||
| 63 | flash_proxy override function deleteProperty(prop:*):Boolean { | ||
| 64 | var i:int = _props.indexOf(prop); | ||
| 65 | if (i != -1) { | ||
| 66 | _props.splice(i, 1); | ||
| 67 | delete _values[prop]; | ||
| 68 | return true; | ||
| 69 | } else { | ||
| 70 | return false; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | /** @private **/ | ||
| 75 | override flash_proxy function nextNameIndex(index:int):int { | ||
| 76 | if (index >= _props.length) { | ||
| 77 | return 0; | ||
| 78 | } else { | ||
| 79 | var l:int = _props.length; | ||
| 80 | var p:String; | ||
| 81 | for (var i:int = index; i < l; i++) { | ||
| 82 | p = _props[i]; | ||
| 83 | if (_numbers[p]) { | ||
| 84 | if (this[p] || this[p] == 0) { | ||
| 85 | return i + 1; | ||
| 86 | } | ||
| 87 | } else if (this[p] != null) { | ||
| 88 | return i + 1; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | /** @private **/ | ||
| 96 | override flash_proxy function nextName(index:int):String { | ||
| 97 | return _props[index - 1]; | ||
| 98 | } | ||
| 99 | |||
| 100 | /** @private **/ | ||
| 101 | protected function setProp(name:String, value:*):void { | ||
| 102 | if (!(name in _values)) { | ||
| 103 | _props[_props.length] = name; | ||
| 104 | } | ||
| 105 | _values[name] = value; | ||
| 106 | } | ||
| 107 | |||
| 108 | protected function copyPropsTo(vars:VarsCore):VarsCore { | ||
| 109 | for (var p:String in this) { | ||
| 110 | vars[p] = this[p]; | ||
| 111 | } | ||
| 112 | return vars; | ||
| 113 | } | ||
| 114 | |||
| 115 | |||
| 116 | |||
| 117 | //---- GETTERS / SETTERS ------------------------------------------------------------------------ | ||
| 118 | |||
| 119 | /** @private For backwards compatibility **/ | ||
| 120 | public function get exposedVars():Object { | ||
| 121 | return this; | ||
| 122 | } | ||
| 123 | |||
| 124 | |||
| 125 | } | ||
| 126 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | public class Back { | ||
| 3 | public static function easeIn (t:Number, b:Number, c:Number, d:Number, s:Number = 1.70158):Number { | ||
| 4 | return c*(t/=d)*t*((s+1)*t - s) + b; | ||
| 5 | } | ||
| 6 | public static function easeOut (t:Number, b:Number, c:Number, d:Number, s:Number = 1.70158):Number { | ||
| 7 | return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; | ||
| 8 | } | ||
| 9 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number, s:Number = 1.70158):Number { | ||
| 10 | if ((t/=d*0.5) < 1) return c*0.5*(t*t*(((s*=(1.525))+1)*t - s)) + b; | ||
| 11 | return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; | ||
| 12 | } | ||
| 13 | } | ||
| 14 | } |
| 1 | package com.greensock.easing { | ||
| 2 | public class Bounce { | ||
| 3 | public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 4 | if ((t/=d) < (1/2.75)) { | ||
| 5 | return c*(7.5625*t*t) + b; | ||
| 6 | } else if (t < (2/2.75)) { | ||
| 7 | return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; | ||
| 8 | } else if (t < (2.5/2.75)) { | ||
| 9 | return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; | ||
| 10 | } else { | ||
| 11 | return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; | ||
| 12 | } | ||
| 13 | } | ||
| 14 | public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 15 | return c - easeOut(d-t, 0, c, d) + b; | ||
| 16 | } | ||
| 17 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 18 | if (t < d*0.5) return easeIn (t*2, 0, c, d) * .5 + b; | ||
| 19 | else return easeOut (t*2-d, 0, c, d) * .5 + c*.5 + b; | ||
| 20 | } | ||
| 21 | } | ||
| 22 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | public class Circ { | ||
| 3 | public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 4 | return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; | ||
| 5 | } | ||
| 6 | public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 7 | return c * Math.sqrt(1 - (t=t/d-1)*t) + b; | ||
| 8 | } | ||
| 9 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 10 | if ((t/=d*0.5) < 1) return -c*0.5 * (Math.sqrt(1 - t*t) - 1) + b; | ||
| 11 | return c*0.5 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; | ||
| 12 | } | ||
| 13 | } | ||
| 14 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | |||
| 3 | public class Cubic { | ||
| 4 | public static const power:uint = 2; | ||
| 5 | |||
| 6 | public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 7 | return c*(t/=d)*t*t + b; | ||
| 8 | } | ||
| 9 | public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 10 | return c*((t=t/d-1)*t*t + 1) + b; | ||
| 11 | } | ||
| 12 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 13 | if ((t/=d*0.5) < 1) return c*0.5*t*t*t + b; | ||
| 14 | return c*0.5*((t-=2)*t*t + 2) + b; | ||
| 15 | } | ||
| 16 | } | ||
| 17 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | /** | ||
| 3 | * EaseLookup enables you to find the easing function associated with a particular name (String), | ||
| 4 | * like "strongEaseOut" which can be useful when loading in XML data that comes in as Strings but | ||
| 5 | * needs to be translated to native function references. | ||
| 6 | * | ||
| 7 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 8 | * | ||
| 9 | * @author Jack Doyle, jack@greensock.com | ||
| 10 | */ | ||
| 11 | public class EaseLookup { | ||
| 12 | /** @private **/ | ||
| 13 | private static var _lookup:Object; | ||
| 14 | |||
| 15 | /** | ||
| 16 | * Finds the easing function associated with a particular name (String), like "strongEaseOut". This can be useful when | ||
| 17 | * loading in XML data that comes in as Strings but needs to be translated to native function references. You can pass in | ||
| 18 | * the name with or without the period, and it is case insensitive, so any of the following will find the Strong.easeOut function: <br /><br /><code> | ||
| 19 | * EaseLookup.find("Strong.easeOut") <br /> | ||
| 20 | * EaseLookup.find("strongEaseOut") <br /> | ||
| 21 | * EaseLookup.find("strongeaseout") <br /><br /></code> | ||
| 22 | * | ||
| 23 | * You can translate Strings directly when tweening, like this: <br /><code> | ||
| 24 | * TweenLite.to(mc, 1, {x:100, ease:EaseLookup.find(myString)});<br /><br /></code> | ||
| 25 | * | ||
| 26 | * @param name The name of the easing function, with or without the period and case insensitive (i.e. "Strong.easeOut" or "strongEaseOut") | ||
| 27 | * @return The easing function associated with the name | ||
| 28 | */ | ||
| 29 | public static function find(name:String):Function { | ||
| 30 | if (_lookup == null) { | ||
| 31 | buildLookup(); | ||
| 32 | } | ||
| 33 | return _lookup[name.toLowerCase()]; | ||
| 34 | } | ||
| 35 | |||
| 36 | /** @private **/ | ||
| 37 | private static function buildLookup():void { | ||
| 38 | _lookup = {}; | ||
| 39 | |||
| 40 | addInOut(Back, ["back"]); | ||
| 41 | addInOut(Bounce, ["bounce"]); | ||
| 42 | addInOut(Circ, ["circ", "circular"]); | ||
| 43 | addInOut(Cubic, ["cubic"]); | ||
| 44 | addInOut(Elastic, ["elastic"]); | ||
| 45 | addInOut(Expo, ["expo", "exponential"]); | ||
| 46 | addInOut(Linear, ["linear"]); | ||
| 47 | addInOut(Quad, ["quad", "quadratic"]); | ||
| 48 | addInOut(Quart, ["quart","quartic"]); | ||
| 49 | addInOut(Quint, ["quint", "quintic", "strong"]); | ||
| 50 | addInOut(Sine, ["sine"]); | ||
| 51 | |||
| 52 | _lookup["linear.easenone"] = _lookup["lineareasenone"] = Linear.easeNone; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** @private **/ | ||
| 56 | private static function addInOut(easeClass:Class, names:Array):void { | ||
| 57 | var name:String; | ||
| 58 | var i:int = names.length; | ||
| 59 | while (i-- > 0) { | ||
| 60 | name = names[i].toLowerCase(); | ||
| 61 | _lookup[name + ".easein"] = _lookup[name + "easein"] = easeClass.easeIn; | ||
| 62 | _lookup[name + ".easeout"] = _lookup[name + "easeout"] = easeClass.easeOut; | ||
| 63 | _lookup[name + ".easeinout"] = _lookup[name + "easeinout"] = easeClass.easeInOut; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | |||
| 68 | } | ||
| 69 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | public class Elastic { | ||
| 3 | private static const _2PI:Number = Math.PI * 2; | ||
| 4 | |||
| 5 | public static function easeIn (t:Number, b:Number, c:Number, d:Number, a:Number = 0, p:Number = 0):Number { | ||
| 6 | var s:Number; | ||
| 7 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; | ||
| 8 | if (!a || (c > 0 && a < c) || (c < 0 && a < -c)) { a=c; s = p/4; } | ||
| 9 | else s = p/_2PI * Math.asin (c/a); | ||
| 10 | return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*_2PI/p )) + b; | ||
| 11 | } | ||
| 12 | public static function easeOut (t:Number, b:Number, c:Number, d:Number, a:Number = 0, p:Number = 0):Number { | ||
| 13 | var s:Number; | ||
| 14 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; | ||
| 15 | if (!a || (c > 0 && a < c) || (c < 0 && a < -c)) { a=c; s = p/4; } | ||
| 16 | else s = p/_2PI * Math.asin (c/a); | ||
| 17 | return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*_2PI/p ) + c + b); | ||
| 18 | } | ||
| 19 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number, a:Number = 0, p:Number = 0):Number { | ||
| 20 | var s:Number; | ||
| 21 | if (t==0) return b; if ((t/=d*0.5)==2) return b+c; if (!p) p=d*(.3*1.5); | ||
| 22 | if (!a || (c > 0 && a < c) || (c < 0 && a < -c)) { a=c; s = p/4; } | ||
| 23 | else s = p/_2PI * Math.asin (c/a); | ||
| 24 | if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*_2PI/p )) + b; | ||
| 25 | return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*_2PI/p )*.5 + c + b; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | public class Expo { | ||
| 3 | public static function easeIn(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 4 | return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b - c * 0.001; | ||
| 5 | } | ||
| 6 | public static function easeOut(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 7 | return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; | ||
| 8 | } | ||
| 9 | public static function easeInOut(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 10 | if (t==0) return b; | ||
| 11 | if (t==d) return b+c; | ||
| 12 | if ((t/=d*0.5) < 1) return c*0.5 * Math.pow(2, 10 * (t - 1)) + b; | ||
| 13 | return c*0.5 * (-Math.pow(2, -10 * --t) + 2) + b; | ||
| 14 | } | ||
| 15 | } | ||
| 16 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.0 | ||
| 3 | * DATE: 10/18/2009 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.easing { | ||
| 8 | import flash.utils.Dictionary; | ||
| 9 | import com.greensock.TweenLite; | ||
| 10 | /** | ||
| 11 | * TweenMax (AS3 only) has built-in algorithms that speed up the processing of certain easing equations but in order | ||
| 12 | * to take advantage of those optimizations, you must activate the easing equations first (you only need to | ||
| 13 | * activate them ONCE in your swf). The following easing equations from the com.greensock.easing package are | ||
| 14 | * eligible for activation: | ||
| 15 | * <code> | ||
| 16 | * <ul> | ||
| 17 | * <li>Linear (easeIn, easeOut, easeInOut, and easeNone)</li> | ||
| 18 | * <li>Quad (easeIn, easeOut, and easeInOut)</li> | ||
| 19 | * <li>Cubic (easeIn, easeOut, and easeInOut)</li> | ||
| 20 | * <li>Quart (easeIn, easeOut, and easeInOut)</li> | ||
| 21 | * <li>Quint (easeIn, easeOut, and easeInOut)</li> | ||
| 22 | * <li>Strong (easeIn, easeOut, and easeInOut)</li> | ||
| 23 | * </ul><br /> | ||
| 24 | * </code> | ||
| 25 | * | ||
| 26 | * <b>EXAMPLE</b><br /><br /> | ||
| 27 | * | ||
| 28 | * <code> | ||
| 29 | * import com.greensock.easing.*;<br /><br /> | ||
| 30 | * | ||
| 31 | * //activate the optimized ease classes<br /> | ||
| 32 | * FastEase.activate([Strong, Linear, Quad]);<br /><br /> | ||
| 33 | * | ||
| 34 | * //then tween as usual (you don't have to do anything special in your tweens)<br /> | ||
| 35 | * TweenMax.to(mc, 2, {x:200, ease:Linear.easeNone});<br /><br /> | ||
| 36 | * </code> | ||
| 37 | * | ||
| 38 | * Once activated, the easing calculations run about <b>35-80% faster!</b> Keep in mind that the easing calculations are only one small part | ||
| 39 | * of the tweening engine, so you may only see a 2-15% improvement overall depending on the equation and quantity of simultaneous tweens. | ||
| 40 | * | ||
| 41 | * Notes: <br /> | ||
| 42 | * <ul> | ||
| 43 | * <li>TweenLite does <b>NOT</b> have the internal algorithms in place to take advantage of optimized eases at this time (to conserve file size).</li> | ||
| 44 | * <li>Activating an ease multiple times doesn't hurt or help</li> | ||
| 45 | * </ul> | ||
| 46 | * | ||
| 47 | * @param easeClasses An Array containing the easing classes to activate, like [Strong, Linear, Quad]. It will automatically activate the easeIn, easeOut, easeInOut, and (if available) easeNone easing equations for each class in the Array. | ||
| 48 | */ | ||
| 49 | public class FastEase { | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Normally you should use the <code>FastEase.activate()</code> method to activate optimized eases, but if you | ||
| 53 | * want to activate an ease that is NOT in the com.greensock.easing package (for example | ||
| 54 | * <code>fl.motion.easing.Quadratic</code>), you can register individual easing equations with | ||
| 55 | * this method. For example: | ||
| 56 | * | ||
| 57 | * <code> | ||
| 58 | * import fl.motion.easing.Quadratic;<br /> | ||
| 59 | * import com.greensock.easing.FastEase;<br /><br /> | ||
| 60 | * | ||
| 61 | * FastEase.activateEase(Quadratic.easeIn, 1, 1); | ||
| 62 | * </code> | ||
| 63 | * | ||
| 64 | * @param ease The easing equation (function) to activate. For example, Quadratic.easeIn | ||
| 65 | * @param type The type of ease (in, out, or inOut) where easeIn is 1, easeOut is 2, and easeInOut is 3. | ||
| 66 | * @param power The magnitude or power of the ease. For example, Linear is 0, Quad is 1, Cubic is 2, Quart is 3 and Quint and Strong are 4. | ||
| 67 | */ | ||
| 68 | public static function activateEase(ease:Function, type:int, power:uint):void { | ||
| 69 | TweenLite.fastEaseLookup[ease] = [type, power]; | ||
| 70 | } | ||
| 71 | |||
| 72 | /** | ||
| 73 | * TweenMax (AS3 only) has built-in algorithms that speed up the processing of certain easing equations but in order | ||
| 74 | * to take advantage of those optimizations, you must activate the easing equations first (you only need to | ||
| 75 | * activate them ONCE in your swf). The following easing equations from the com.greensock.easing package are | ||
| 76 | * eligible for activation: | ||
| 77 | * <code> | ||
| 78 | * <ul> | ||
| 79 | * <li>Linear (easeIn, easeOut, easeInOut, and easeNone)</li> | ||
| 80 | * <li>Quad (easeIn, easeOut, and easeInOut)</li> | ||
| 81 | * <li>Cubic (easeIn, easeOut, and easeInOut)</li> | ||
| 82 | * <li>Quart (easeIn, easeOut, and easeInOut)</li> | ||
| 83 | * <li>Quint (easeIn, easeOut, and easeInOut)</li> | ||
| 84 | * <li>Strong (easeIn, easeOut, and easeInOut)</li> | ||
| 85 | * </ul><br /> | ||
| 86 | * </code> | ||
| 87 | * | ||
| 88 | * <b>EXAMPLE</b><br /><br /> | ||
| 89 | * | ||
| 90 | * <code> | ||
| 91 | * import com.greensock.easing.*;<br /><br /> | ||
| 92 | * | ||
| 93 | * FastEase.activate([Strong, Linear, Quad]);<br /><br /> | ||
| 94 | * </code> | ||
| 95 | * | ||
| 96 | * Notes: <br /> | ||
| 97 | * <ul> | ||
| 98 | * <li>TweenLite does <b>NOT</b> have the internal algorithms in place to take advantage of optimized eases at this time (to conserve file size).</li> | ||
| 99 | * <li>Activating an ease multiple times doesn't hurt or help</li> | ||
| 100 | * </ul> | ||
| 101 | * | ||
| 102 | * @param easeClasses An Array containing the easing classes to activate, like [Strong, Linear, Quad]. It will automatically activate the easeIn, easeOut, easeInOut, and (if available) easeNone easing equations for each class in the Array. | ||
| 103 | */ | ||
| 104 | public static function activate(easeClasses:Array):void { | ||
| 105 | var i:int = easeClasses.length, easeClass:Object; | ||
| 106 | while (i--) { | ||
| 107 | easeClass = easeClasses[i]; | ||
| 108 | if (easeClass.hasOwnProperty("power")) { | ||
| 109 | activateEase(easeClass.easeIn, 1, easeClass.power); | ||
| 110 | activateEase(easeClass.easeOut, 2, easeClass.power); | ||
| 111 | activateEase(easeClass.easeInOut, 3, easeClass.power); | ||
| 112 | if (easeClass.hasOwnProperty("easeNone")) { | ||
| 113 | activateEase(easeClass.easeNone, 1, 0); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | } | ||
| 120 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | |||
| 3 | public class Linear { | ||
| 4 | public static const power:uint = 0; | ||
| 5 | |||
| 6 | public static function easeNone (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 7 | return c*t/d + b; | ||
| 8 | } | ||
| 9 | public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 10 | return c*t/d + b; | ||
| 11 | } | ||
| 12 | public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 13 | return c*t/d + b; | ||
| 14 | } | ||
| 15 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 16 | return c*t/d + b; | ||
| 17 | } | ||
| 18 | } | ||
| 19 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | |||
| 3 | public class Quad { | ||
| 4 | public static const power:uint = 1; | ||
| 5 | |||
| 6 | public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 7 | return c*(t/=d)*t + b; | ||
| 8 | } | ||
| 9 | public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 10 | return -c *(t/=d)*(t-2) + b; | ||
| 11 | } | ||
| 12 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 13 | if ((t/=d*0.5) < 1) return c*0.5*t*t + b; | ||
| 14 | return -c*0.5 * ((--t)*(t-2) - 1) + b; | ||
| 15 | } | ||
| 16 | } | ||
| 17 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | |||
| 3 | public class Quart { | ||
| 4 | public static const power:uint = 3; | ||
| 5 | |||
| 6 | public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 7 | return c*(t/=d)*t*t*t + b; | ||
| 8 | } | ||
| 9 | public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 10 | return -c * ((t=t/d-1)*t*t*t - 1) + b; | ||
| 11 | } | ||
| 12 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 13 | if ((t/=d*0.5) < 1) return c*0.5*t*t*t*t + b; | ||
| 14 | return -c*0.5 * ((t-=2)*t*t*t - 2) + b; | ||
| 15 | } | ||
| 16 | } | ||
| 17 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | |||
| 3 | public class Quint { | ||
| 4 | public static const power:uint = 4; | ||
| 5 | |||
| 6 | public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 7 | return c*(t/=d)*t*t*t*t + b; | ||
| 8 | } | ||
| 9 | public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 10 | return c*((t=t/d-1)*t*t*t*t + 1) + b; | ||
| 11 | } | ||
| 12 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 13 | if ((t/=d*0.5) < 1) return c*0.5*t*t*t*t*t + b; | ||
| 14 | return c*0.5*((t-=2)*t*t*t*t + 2) + b; | ||
| 15 | } | ||
| 16 | } | ||
| 17 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.6 | ||
| 3 | * DATE: 1/19/2010 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/roughease/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.easing { | ||
| 8 | /** | ||
| 9 | * Most easing equations give a smooth, gradual transition between the start and end values, but RoughEase provides | ||
| 10 | * an easy way to get a rough, jagged effect instead. You can define an ease that it will use as a template (like a | ||
| 11 | * general guide - Linear.easeNone is the default) and then it will randomly plot points that wander from that template. | ||
| 12 | * The strength parameter controls how far from the template ease the points are allowed to go (a small number like | ||
| 13 | * 0.1 keeps it very close to the template ease whereas a larger number like 2 creates much larger jumps). You can | ||
| 14 | * also control the number of points in the ease, making it jerk more or less frequently. And lastly, you can associate | ||
| 15 | * a name with each RoughEase instance and retrieve it later like RoughEase.byName("myEaseName"). Since creating | ||
| 16 | * the initial RoughEase is the most processor-intensive part, it's a good idea to reuse instances if/when you can.<br /><br /> | ||
| 17 | * | ||
| 18 | * <b>EXAMPLE CODE</b><br /><br /><code> | ||
| 19 | * import com.greensock.TweenLite;<br /> | ||
| 20 | * import com.greensock.easing.RoughEase;<br /><br /> | ||
| 21 | * | ||
| 22 | * TweenLite.from(mc, 3, {alpha:0, ease:RoughEase.create(1, 15)});<br /><br /> | ||
| 23 | * | ||
| 24 | * //or create an instance directly<br /> | ||
| 25 | * var rough:RoughEase = new RoughEase(1.5, 30, true, Strong.easeOut, "none", true, "superRoughEase");<br /> | ||
| 26 | * TweenLite.to(mc, 3, {y:300, ease:rough.ease});<br /><br /> | ||
| 27 | * | ||
| 28 | * //and later, you can find the ease by name like:<br /> | ||
| 29 | * TweenLite.to(mc, 3, {y:300, ease:RoughEase.byName("superRoughEase")}); | ||
| 30 | * </code><br /><br /> | ||
| 31 | * | ||
| 32 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 33 | * | ||
| 34 | * @author Jack Doyle, jack@greensock.com | ||
| 35 | */ | ||
| 36 | public class RoughEase { | ||
| 37 | /** @private **/ | ||
| 38 | private static var _all:Object = {}; //keeps track of all instances so we can find them by name. | ||
| 39 | /** @private **/ | ||
| 40 | private static var _count:uint = 0; | ||
| 41 | |||
| 42 | /** @private **/ | ||
| 43 | private var _name:String; | ||
| 44 | /** @private **/ | ||
| 45 | private var _first:EasePoint; | ||
| 46 | /** @private **/ | ||
| 47 | private var _last:EasePoint; | ||
| 48 | |||
| 49 | /** | ||
| 50 | * Constructor | ||
| 51 | * | ||
| 52 | * @param strength amount of variance from the templateEase (Linear.easeNone by default) that each random point can be placed. A low number like 0.1 will hug very closely to the templateEase whereas a larger number like 2 will allow the values to wander further away from the templateEase. | ||
| 53 | * @param points quantity of random points to plot in the ease. A larger number will cause more (and quicker) flickering. | ||
| 54 | * @param restrictMaxAndMin If true, the ease will prevent random points from exceeding the end value or dropping below the starting value. For example, if you're tweening the x property from 0 to 100, the RoughEase would force all random points to stay between 0 and 100 if restrictMaxAndMin is true, but if it is false, a x could potentially jump above 100 or below 0 at some point during the tween (it would always end at 100 though). | ||
| 55 | * @param templateEase an easing equation that should be used as a template or guide. Then random points are plotted at a certain distance away from the templateEase (based on the strength parameter). The default is Linear.easeNone. | ||
| 56 | * @param taper to make the strength of the roughness taper towards the end or beginning, use "out" or "in" respectively here (default is "none") . | ||
| 57 | * @param randomize to randomize the placement of the points, set randomize to true (otherwise the points will zig-zag evenly across the ease) | ||
| 58 | * @param name a name to associate with the ease so that you can use RoughEase.byName() to look it up later. Of course you should always make sure you use a unique name for each ease (if you leave it blank, a name will automatically be generated). | ||
| 59 | */ | ||
| 60 | public function RoughEase(strength:Number=1, points:uint=20, restrictMaxAndMin:Boolean=false, templateEase:Function=null, taper:String="none", randomize:Boolean=true, name:String="") { | ||
| 61 | if (name == "") { | ||
| 62 | _count++; | ||
| 63 | _name = "roughEase" + _count; | ||
| 64 | } else { | ||
| 65 | _name = name; | ||
| 66 | } | ||
| 67 | if (taper == "" || taper == null) { | ||
| 68 | taper = "none"; | ||
| 69 | } | ||
| 70 | _all[_name] = this; | ||
| 71 | var a:Array = []; | ||
| 72 | var cnt:uint = 0; | ||
| 73 | var x:Number, y:Number, bump:Number, invX:Number, obj:Object; | ||
| 74 | var i:uint = points; | ||
| 75 | while (i--) { | ||
| 76 | x = randomize ? Math.random() : (1 / points) * i; | ||
| 77 | y = (templateEase != null) ? templateEase(x, 0, 1, 1) : x; | ||
| 78 | if (taper == "none") { | ||
| 79 | bump = 0.4 * strength; | ||
| 80 | } else if (taper == "out") { | ||
| 81 | invX = 1 - x; | ||
| 82 | bump = invX * invX * strength * 0.4; | ||
| 83 | } else { | ||
| 84 | bump = x * x * strength * 0.4; | ||
| 85 | } | ||
| 86 | if (randomize) { | ||
| 87 | y += (Math.random() * bump) - (bump * 0.5); | ||
| 88 | } else if (i % 2) { | ||
| 89 | y += bump * 0.5; | ||
| 90 | } else { | ||
| 91 | y -= bump * 0.5; | ||
| 92 | } | ||
| 93 | if (restrictMaxAndMin) { | ||
| 94 | if (y > 1) { | ||
| 95 | y = 1; | ||
| 96 | } else if (y < 0) { | ||
| 97 | y = 0; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | a[cnt++] = {x:x, y:y}; | ||
| 101 | } | ||
| 102 | a.sortOn("x", Array.NUMERIC); | ||
| 103 | |||
| 104 | _first = _last = new EasePoint(1, 1, null); | ||
| 105 | |||
| 106 | i = points; | ||
| 107 | while (i--) { | ||
| 108 | obj = a[i]; | ||
| 109 | _first = new EasePoint(obj.x, obj.y, _first); | ||
| 110 | } | ||
| 111 | _first = new EasePoint(0, 0, _first); | ||
| 112 | |||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * This static function provides a quick way to create a RoughEase and immediately reference its ease function | ||
| 117 | * in a tween, like:<br /><br /><code> | ||
| 118 | * | ||
| 119 | * TweenLite.from(mc, 2, {alpha:0, ease:RoughEase.create(1.5, 15)});<br /> | ||
| 120 | * </code> | ||
| 121 | * | ||
| 122 | * @param strength amount of variance from the templateEase (Linear.easeNone by default) that each random point can be placed. A low number like 0.1 will hug very closely to the templateEase whereas a larger number like 2 will allow the values to wander further away from the templateEase. | ||
| 123 | * @param points quantity of random points to plot in the ease. A larger number will cause more (and quicker) flickering. | ||
| 124 | * @param restrictMaxAndMin If true, the ease will prevent random points from exceeding the end value or dropping below the starting value. For example, if you're tweening the x property from 0 to 100, the RoughEase would force all random points to stay between 0 and 100 if restrictMaxAndMin is true, but if it is false, a x could potentially jump above 100 or below 0 at some point during the tween (it would always end at 100 though). | ||
| 125 | * @param templateEase an easing equation that should be used as a template or guide. Then random points are plotted at a certain distance away from the templateEase (based on the strength parameter). The default is Linear.easeNone. | ||
| 126 | * @param taper to make the strength of the roughness taper towards the end or beginning, use "out" or "in" respectively here (default is "none") . | ||
| 127 | * @param randomize to randomize the placement of the points, set randomize to true (otherwise the points will zig-zag evenly across the ease) | ||
| 128 | * @param name a name to associate with the ease so that you can use RoughEase.byName() to look it up later. Of course you should always make sure you use a unique name for each ease (if you leave it blank, a name will automatically be generated). | ||
| 129 | * @return easing function | ||
| 130 | */ | ||
| 131 | public static function create(strength:Number=1, points:uint=20, restrictMaxAndMin:Boolean=false, templateEase:Function=null, taper:String="none", randomize:Boolean=true, name:String=""):Function { | ||
| 132 | return new RoughEase(strength, points, restrictMaxAndMin, templateEase, taper, randomize, name).ease; | ||
| 133 | } | ||
| 134 | |||
| 135 | /** | ||
| 136 | * Provides a quick way to look up a RoughEase by its name. | ||
| 137 | * | ||
| 138 | * @param name the name of the RoughEase | ||
| 139 | * @return easing function from the RoughEase associated with the name | ||
| 140 | */ | ||
| 141 | public static function byName(name:String):Function { | ||
| 142 | return _all[name].ease; | ||
| 143 | } | ||
| 144 | |||
| 145 | /** | ||
| 146 | * Easing function that interpolates the numbers | ||
| 147 | * | ||
| 148 | * @param t time | ||
| 149 | * @param b start | ||
| 150 | * @param c change | ||
| 151 | * @param d duration | ||
| 152 | * @return Result of the ease | ||
| 153 | */ | ||
| 154 | public function ease(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 155 | var time:Number = t / d; | ||
| 156 | var p:EasePoint; | ||
| 157 | if (time < 0.5) { | ||
| 158 | p = _first; | ||
| 159 | while (p.time <= time) { | ||
| 160 | p = p.next; | ||
| 161 | } | ||
| 162 | p = p.prev; | ||
| 163 | } else { | ||
| 164 | p = _last; | ||
| 165 | while (p.time >= time) { | ||
| 166 | p = p.prev; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | return b + (p.value + ((time - p.time) / p.gap) * p.change) * c; | ||
| 170 | } | ||
| 171 | |||
| 172 | /** name of the RoughEase instance **/ | ||
| 173 | public function get name():String { | ||
| 174 | return _name; | ||
| 175 | } | ||
| 176 | |||
| 177 | public function set name(s:String):void { | ||
| 178 | delete _all[_name]; | ||
| 179 | _name = s; | ||
| 180 | _all[s] = this; | ||
| 181 | } | ||
| 182 | |||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | internal class EasePoint { | ||
| 187 | public var time:Number; | ||
| 188 | public var gap:Number; | ||
| 189 | public var value:Number; | ||
| 190 | public var change:Number; | ||
| 191 | public var next:EasePoint; | ||
| 192 | public var prev:EasePoint; | ||
| 193 | |||
| 194 | public function EasePoint(time:Number, value:Number, next:EasePoint) { | ||
| 195 | this.time = time; | ||
| 196 | this.value = value; | ||
| 197 | if (next) { | ||
| 198 | this.next = next; | ||
| 199 | next.prev = this; | ||
| 200 | this.change = next.value - value; | ||
| 201 | this.gap = next.time - time; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | public class Sine { | ||
| 3 | private static const _HALF_PI:Number = Math.PI * 0.5; | ||
| 4 | |||
| 5 | public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 6 | return -c * Math.cos(t/d * _HALF_PI) + c + b; | ||
| 7 | } | ||
| 8 | public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 9 | return c * Math.sin(t/d * _HALF_PI) + b; | ||
| 10 | } | ||
| 11 | public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { | ||
| 12 | return -c*0.5 * (Math.cos(Math.PI*t/d) - 1) + b; | ||
| 13 | } | ||
| 14 | } | ||
| 15 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.easing { | ||
| 2 | |||
| 3 | public class Strong { | ||
| 4 | public static const power:uint = 4; | ||
| 5 | |||
| 6 | public static function easeIn(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 7 | return c*(t/=d)*t*t*t*t + b; | ||
| 8 | } | ||
| 9 | public static function easeOut(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 10 | return c*((t=t/d-1)*t*t*t*t + 1) + b; | ||
| 11 | } | ||
| 12 | public static function easeInOut(t:Number, b:Number, c:Number, d:Number):Number { | ||
| 13 | if ((t/=d*0.5) < 1) return c*0.5*t*t*t*t*t + b; | ||
| 14 | return c*0.5*((t-=2)*t*t*t*t + 2) + b; | ||
| 15 | } | ||
| 16 | } | ||
| 17 | } |
| 1 | This readme file applies to all eases in this directory EXCEPT the CustomEase, EaseLookup, FastEase, and RoughEase. | ||
| 2 | |||
| 3 | ============================================================================================ | ||
| 4 | Easing Equations | ||
| 5 | (c) 2003 Robert Penner, all rights reserved. | ||
| 6 | This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html. | ||
| 7 | ============================================================================================ | ||
| 8 | |||
| 9 | TERMS OF USE - EASING EQUATIONS | ||
| 10 | |||
| 11 | Open source under the BSD License. | ||
| 12 | |||
| 13 | All rights reserved. | ||
| 14 | |||
| 15 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | ||
| 16 | |||
| 17 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | ||
| 18 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | ||
| 19 | * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. | ||
| 20 | |||
| 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.2 | ||
| 3 | * DATE: 2010-07-28 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.events { | ||
| 8 | |||
| 9 | import flash.events.Event; | ||
| 10 | /** | ||
| 11 | * An Event dispatched by one of the loaders in the LoaderMax system. | ||
| 12 | * <br /><br /> | ||
| 13 | * | ||
| 14 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 15 | * | ||
| 16 | * @author Jack Doyle, jack@greensock.com | ||
| 17 | */ | ||
| 18 | public class LoaderEvent extends Event { | ||
| 19 | /** Dispatched by a LoaderMax (or other loader that may dynamically recognize nested loaders like XMLLoader and SWFLoader) when one of its children begins loading. **/ | ||
| 20 | public static const CHILD_OPEN:String="childOpen"; | ||
| 21 | /** Dispatched by a LoaderMax (or other loader that may dynamically recognize nested loaders like XMLLoader and SWFLoader) when one of its children dispatches a <code>PROGRESS</code> Event. **/ | ||
| 22 | public static const CHILD_PROGRESS:String="childProgress"; | ||
| 23 | /** Dispatched by a LoaderMax (or other loader that may dynamically recognize nested loaders like XMLLoader and SWFLoader) when one of its children aborts its loading. This can happen when the loader fails, when <code>cancel()</code> is manually called, or when another loader is prioritized in the loading queue. **/ | ||
| 24 | public static const CHILD_CANCEL:String="childCancel"; | ||
| 25 | /** Dispatched by a LoaderMax (or other loader that may dynamically recognize nested loaders like XMLLoader and SWFLoader) when one of its children finishes loading. **/ | ||
| 26 | public static const CHILD_COMPLETE:String="childComplete"; | ||
| 27 | /** Dispatched by a LoaderMax (or other loader that may dynamically recognize nested loaders like XMLLoader and SWFLoader) when one of its children fails to load. **/ | ||
| 28 | public static const CHILD_FAIL:String="childFail"; | ||
| 29 | /** Dispatched when the loader begins loading, like when its <code>load()</code> method is called. **/ | ||
| 30 | public static const OPEN:String="open"; | ||
| 31 | /** Dispatched when the loader's <code>bytesLoaded</code> changes. **/ | ||
| 32 | public static const PROGRESS:String="progress"; | ||
| 33 | /** Dispatched when the loader aborts its loading. This can happen when the loader fails, when <code>cancel()</code> is manually called, or when another loader is prioritized in the loading queue. **/ | ||
| 34 | public static const CANCEL:String="cancel"; | ||
| 35 | /** Dispatched when the loader fails. **/ | ||
| 36 | public static const FAIL:String="fail"; | ||
| 37 | /** Dispatched when the loader initializes which means different things for different loaders. For example, a SWFLoader dispatches <code>INIT</code> when it downloads enough of the swf to render the first frame. When a VideoLoader receives MetaData, it dispatches its <code>INIT</code> event, as does an MP3Loader when it receives ID3 data. See the docs for each class for specifics. **/ | ||
| 38 | public static const INIT:String="init"; | ||
| 39 | /** Dispatched when the loader finishes loading. **/ | ||
| 40 | public static const COMPLETE:String="complete"; | ||
| 41 | /** Dispatched when the loader (or one of its children) receives an HTTP_STATUS event (see Adobe docs for specifics). **/ | ||
| 42 | public static const HTTP_STATUS:String="httpStatus"; | ||
| 43 | /** When script access is denied for a particular loader (like if an ImageLoader or SWFLoader tries loading from another domain and the crossdomain.xml file is missing or doesn't grant permission properly), a SCRIPT_ACCESS_DENIED LoaderEvent will be dispatched. **/ | ||
| 44 | public static const SCRIPT_ACCESS_DENIED:String="scriptAccessDenied"; | ||
| 45 | /** Dispatched when the loader (or one of its children) throws any error, like an IO_ERROR or SECURITY_ERROR. **/ | ||
| 46 | public static const ERROR:String="error"; | ||
| 47 | /** Dispatched when the the loader (or one of its children) encounters an IO_ERROR (typically when it cannot find the file at the specified <code>url</code>). **/ | ||
| 48 | public static const IO_ERROR:String="ioError"; | ||
| 49 | /** Dispatched when the loader (or one of its children) encounters a SECURITY_ERROR (see Adobe's docs for details). **/ | ||
| 50 | public static const SECURITY_ERROR:String="securityError"; | ||
| 51 | |||
| 52 | /** @private **/ | ||
| 53 | protected var _target:Object; | ||
| 54 | /** @private **/ | ||
| 55 | protected var _ready:Boolean; | ||
| 56 | |||
| 57 | /** For <code>ERROR, FAIL</code>, and <code>CHILD_FAIL</code> events, this text will give more details about the error or failure. **/ | ||
| 58 | public var text:String; | ||
| 59 | /** Event-related data which varies based on the type of event. For example, VideoLoader dispatches a VIDEO_CUE_POINT event containing data about the cue point. **/ | ||
| 60 | public var data:*; | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Constructor | ||
| 64 | * | ||
| 65 | * @param type Type of event | ||
| 66 | * @param target Target | ||
| 67 | * @param text Error text (if any) | ||
| 68 | */ | ||
| 69 | public function LoaderEvent(type:String, target:Object, text:String="", data:*=null){ | ||
| 70 | super(type, false, false); | ||
| 71 | _target = target; | ||
| 72 | this.text = text; | ||
| 73 | this.data = data; | ||
| 74 | } | ||
| 75 | |||
| 76 | /** @inheritDoc **/ | ||
| 77 | public override function clone():Event{ | ||
| 78 | return new LoaderEvent(this.type, _target, this.text, this.data); | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * The loader associated with the LoaderEvent. This may be different than the <code>currentTarget</code>. | ||
| 83 | * The <code>target</code> always refers to the originating loader, so if there is an ImageLoader nested inside | ||
| 84 | * a LoaderMax instance and you add an event listener to the LoaderMax, if the ImageLoader dispatches an error | ||
| 85 | * event, the event's <code>target</code> will refer to the ImageLoader whereas the <code>currentTarget</code> will | ||
| 86 | * refer to the LoaderMax instance that is currently processing the event. | ||
| 87 | **/ | ||
| 88 | override public function get target():Object { | ||
| 89 | if (_ready) { | ||
| 90 | return _target; | ||
| 91 | } else { | ||
| 92 | //when the event is re-dispatched, Flash's event system checks to see if the target has been set and if it has, Flash will clone() and reset the target so we need to report the target as null the first time and then on subsequent calls, report the real target. | ||
| 93 | _ready = true; | ||
| 94 | } | ||
| 95 | return null; | ||
| 96 | } | ||
| 97 | |||
| 98 | } | ||
| 99 | |||
| 100 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.greensock.events { | ||
| 2 | import flash.events.Event; | ||
| 3 | /** | ||
| 4 | * Used for dispatching events from the GreenSock Tweening Platform. <br /><br /> | ||
| 5 | * | ||
| 6 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 7 | * | ||
| 8 | * @author Jack Doyle, jack@greensock.com | ||
| 9 | */ | ||
| 10 | public class TweenEvent extends Event { | ||
| 11 | /** @private **/ | ||
| 12 | public static const VERSION:Number = 1.1; | ||
| 13 | public static const START:String = "start"; | ||
| 14 | public static const UPDATE:String = "change"; | ||
| 15 | public static const COMPLETE:String = "complete"; | ||
| 16 | public static const REVERSE_COMPLETE:String = "reverseComplete"; | ||
| 17 | public static const REPEAT:String = "repeat"; | ||
| 18 | public static const INIT:String = "init"; | ||
| 19 | |||
| 20 | public function TweenEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) { | ||
| 21 | super(type, bubbles, cancelable); | ||
| 22 | } | ||
| 23 | |||
| 24 | public override function clone():Event { | ||
| 25 | return new TweenEvent(this.type, this.bubbles, this.cancelable); | ||
| 26 | } | ||
| 27 | |||
| 28 | } | ||
| 29 | |||
| 30 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.01 | ||
| 3 | * DATE: 2010-02-03 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://blog.greensock.com/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.layout { | ||
| 8 | /** | ||
| 9 | * Provides constants for defining the alignment of objects. <br /><br /> | ||
| 10 | * | ||
| 11 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 12 | * | ||
| 13 | * @author Jack Doyle, jack@greensock.com | ||
| 14 | */ | ||
| 15 | public class AlignMode { | ||
| 16 | |||
| 17 | /** Align with the top of the area. **/ | ||
| 18 | public static const TOP:String = "top"; | ||
| 19 | /** Align with the center of the area. **/ | ||
| 20 | public static const CENTER:String = "center"; | ||
| 21 | /** Align with the right side of the area. **/ | ||
| 22 | public static const RIGHT:String = "right"; | ||
| 23 | /** Align with the left side of the area. **/ | ||
| 24 | public static const LEFT:String = "left"; | ||
| 25 | /** Align with the bottom of the area. **/ | ||
| 26 | public static const BOTTOM:String = "bottom"; | ||
| 27 | |||
| 28 | } | ||
| 29 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.56 | ||
| 3 | * DATE: 2010-06-25 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.greensock.com/autofitarea/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.layout { | ||
| 8 | import flash.display.BitmapData; | ||
| 9 | import flash.display.DisplayObject; | ||
| 10 | import flash.display.DisplayObjectContainer; | ||
| 11 | import flash.display.Graphics; | ||
| 12 | import flash.display.Shape; | ||
| 13 | import flash.events.Event; | ||
| 14 | import flash.geom.ColorTransform; | ||
| 15 | import flash.geom.Matrix; | ||
| 16 | import flash.geom.Rectangle; | ||
| 17 | /** | ||
| 18 | * AutoFitArea allows you to define a rectangular area and then <code>attach()</code> DisplayObjects | ||
| 19 | * so that they automatically fill the area, scaling/stretching in any of the following modes: <code>STRETCH, | ||
| 20 | * PROPORTIONAL_INSIDE, PROPORTIONAL_OUTSIDE, NONE, WIDTH_ONLY,</code> or <code>HEIGHT_ONLY</code>. Horizontally | ||
| 21 | * align the attached DisplayObjects left, center, or right. Vertically align them top, center, or bottom. | ||
| 22 | * AutoFitArea extends the <code>Shape</code> class, so you can alter the width/height/scaleX/scaleY/x/y | ||
| 23 | * properties of the AutoFitArea and then all of the attached objects will automatically be affected. | ||
| 24 | * Attach as many DisplayObjects as you want. To make visualization easy, you can set the <code>previewColor</code> | ||
| 25 | * to any color and set the <code>preview</code> property to true in order to see the area on the stage | ||
| 26 | * (or simply use it like a regular Shape by adding it to the display list with <code>addChild()</code>, but the | ||
| 27 | * <code>preview</code> property makes it simpler because it automatically ensures that it is behind | ||
| 28 | * all of its attached DisplayObjects in the stacking order). | ||
| 29 | * <br /><br /> | ||
| 30 | * | ||
| 31 | * When you <code>attach()</code> a DisplayObject, you can define a minimum and maximum width and height. | ||
| 32 | * AutoFitArea doesn't require that the DisplayObject's registration point be in its upper left corner | ||
| 33 | * either. You can even set the <code>calculateVisible</code> parameter to true when attaching an object | ||
| 34 | * so that AutoFitArea will ignore masked areas inside the DisplayObject (this is more processor-intensive, | ||
| 35 | * so beware).<br /><br /> | ||
| 36 | * | ||
| 37 | * For scaling, AutoFitArea alters the DisplayObject's <code>width</code> and/or <code>height</code> | ||
| 38 | * properties unless it is rotated in which case it alters the DisplayObject's <code>transform.matrix</code> | ||
| 39 | * directly so that accurate stretching/skewing can be accomplished. <br /><br /> | ||
| 40 | * | ||
| 41 | * There is also a <code>LiquidArea</code> class that extends AutoFitArea and integrates with | ||
| 42 | * <a href="http://www.greensock.com/liquidstage/">LiquidStage</a> so that it automatically | ||
| 43 | * adjusts its size whenever the stage is resized. This makes it simple to create things like | ||
| 44 | * a background that proportionally fills the stage or a bar that always stretches horizontally | ||
| 45 | * to fill the stage but stays stuck to the bottom, etc.<br /><br /> | ||
| 46 | * | ||
| 47 | * @example Example AS3 code:<listing version="3.0"> | ||
| 48 | import com.greensock.layout.~~; | ||
| 49 | |||
| 50 | //create a 300x100 rectangular area at x:50, y:70 that stretches when the stage resizes (as though its top left and bottom right corners are pinned to their corresponding PinPoints on the stage) | ||
| 51 | var area:AutoFitArea = new AutoFitArea(this, 50, 70, 300, 100); | ||
| 52 | |||
| 53 | //attach a "myImage" Sprite to the area and set its ScaleMode to PROPORTIONAL_INSIDE and horizontally and vertically align it in the center of the area | ||
| 54 | area.attach(myImage, ScaleMode.PROPORTIONAL_INSIDE, AlignMode.CENTER, AlignMode.CENTER); | ||
| 55 | |||
| 56 | //if you'd like to preview the area visually, set preview to true (by default previewColor is red) | ||
| 57 | area.preview = true; | ||
| 58 | |||
| 59 | //attach a CHANGE event listener to the area | ||
| 60 | area.addEventListener(Event.CHANGE, onAreaUpdate); | ||
| 61 | function onAreaUpdate(event:Event):void { | ||
| 62 | trace("updated AutoFitArea"); | ||
| 63 | } | ||
| 64 | |||
| 65 | //to create an AutoFitArea exactly around a "myImage" DisplayObject so that it conforms its initial dimensions around the DisplayObject, use the static createAround() method: | ||
| 66 | var area:AutoFitArea = AutoFitArea.createAround(myImage); | ||
| 67 | |||
| 68 | </listing> | ||
| 69 | * | ||
| 70 | * | ||
| 71 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the license that came with your Club GreenSock membership and is <b>ONLY</b> to be used by corporate or "Shockingly Green" Club GreenSock members. To learn more about Club GreenSock, visit <a href="http://www.greensock.com/club/">http://www.greensock.com/club/</a>. | ||
| 72 | * | ||
| 73 | * @author Jack Doyle, jack@greensock.com | ||
| 74 | */ | ||
| 75 | public class AutoFitArea extends Shape { | ||
| 76 | /** @private **/ | ||
| 77 | public static const version:Number = 1.56; | ||
| 78 | |||
| 79 | /** @private **/ | ||
| 80 | private static var _bd:BitmapData; | ||
| 81 | /** @private **/ | ||
| 82 | private static var _rect:Rectangle = new Rectangle(0, 0, 2800, 2800); | ||
| 83 | /** @private **/ | ||
| 84 | private static var _matrix:Matrix = new Matrix(); | ||
| 85 | |||
| 86 | /** @private **/ | ||
| 87 | protected var _parent:DisplayObjectContainer; | ||
| 88 | /** @private **/ | ||
| 89 | protected var _previewColor:uint; | ||
| 90 | /** @private **/ | ||
| 91 | protected var _rootItem:AutoFitItem; | ||
| 92 | /** @private **/ | ||
| 93 | protected var _hasListener:Boolean; | ||
| 94 | /** @private **/ | ||
| 95 | protected var _preview:Boolean; | ||
| 96 | /** @private **/ | ||
| 97 | protected var _tweenMode:Boolean; | ||
| 98 | /** @private **/ | ||
| 99 | protected var _width:Number; | ||
| 100 | /** @private **/ | ||
| 101 | protected var _height:Number; | ||
| 102 | |||
| 103 | /** | ||
| 104 | * Constructor | ||
| 105 | * | ||
| 106 | * @param parent The parent DisplayObjectContainer in which the AutoFitArea should be created. All objects that get attached must share the same parent. | ||
| 107 | * @param x x coordinate of the AutoFitArea's upper left corner | ||
| 108 | * @param y y coordinate of the AutoFitArea's upper left corner | ||
| 109 | * @param width width of the AutoFitArea | ||
| 110 | * @param height height of the AutoFitArea | ||
| 111 | * @param previewColor color of the AutoFitArea (which won't be seen unless you set preview to true or manually add it to the display list with addChild()) | ||
| 112 | */ | ||
| 113 | public function AutoFitArea(parent:DisplayObjectContainer, x:Number=0, y:Number=0, width:Number=100, height:Number=100, previewColor:uint=0xFF0000) { | ||
| 114 | super(); | ||
| 115 | super.x = x; | ||
| 116 | super.y = y; | ||
| 117 | if (parent == null) { | ||
| 118 | throw new Error("AutoFitArea parent cannot be null"); | ||
| 119 | } | ||
| 120 | _parent = parent; | ||
| 121 | _width = width; | ||
| 122 | _height = height; | ||
| 123 | _redraw(previewColor); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Creates an AutoFitArea with its initial dimensions fit precisely around a target DisplayObject. It also attaches | ||
| 128 | * the target DisplayObject immediately. | ||
| 129 | * | ||
| 130 | * @param target The target DisplayObject whose position and dimensions the AutoFitArea should match initially. | ||
| 131 | * @param scaleMode Determines how the target should be scaled to fit the AutoFitArea. ScaleMode choices are: <code>STRETCH, PROPORTIONAL_INSIDE, PROPORTIONAL_OUTSIDE, NONE, WIDTH_ONLY,</code> or <code>HEIGHT_ONLY</code>. | ||
| 132 | * @param hAlign Horizontal alignment of the target inside the AutoFitArea. AlignMode choices are: <code>LEFT</code>, <code>CENTER</code>, and <code>RIGHT</code>. | ||
| 133 | * @param vAlign Vertical alignment of the target inside the AutoFitArea. AlignMode choices are: <code>TOP</code>, <code>CENTER</code>, and <code>BOTTOM</code>. | ||
| 134 | * @param crop If true, a mask will be created so that the target will be cropped wherever it exceeds the bounds of the AutoFitArea. | ||
| 135 | * @param minWidth Minimum width to which the target is allowed to scale | ||
| 136 | * @param minHeight Minimum height to which the target is allowed to scale | ||
| 137 | * @param maxWidth Maximum width to which the target is allowed to scale | ||
| 138 | * @param maxHeight Maximum height to which the target is allowed to scale | ||
| 139 | * @param previewColor color of the AutoFitArea (which won't be seen unless you set preview to true or manually add it to the display list with addChild()) | ||
| 140 | * @param calculateVisible If true, only the visible portions of the target will be taken into account when determining its position and scale which can be useful for objects that have masks applied (otherwise, Flash reports their width/height and getBounds() values including the masked portions). Setting <code>calculateVisible</code> to <code>true</code> degrades performance, so only use it when absolutely necessary. | ||
| 141 | * @return An AutoFitArea instance | ||
| 142 | */ | ||
| 143 | public static function createAround(target:DisplayObject, scaleMode:String="proportionalInside", hAlign:String="center", vAlign:String="center", crop:Boolean=false, minWidth:Number=0, minHeight:Number=0, maxWidth:Number=999999999, maxHeight:Number=999999999, previewColor:uint=0xFF0000, calculateVisible:Boolean=false):AutoFitArea { | ||
| 144 | var bounds:Rectangle = (calculateVisible) ? getVisibleBounds(target, target.parent) : target.getBounds(target.parent); | ||
| 145 | var afa:AutoFitArea = new AutoFitArea(target.parent, bounds.x, bounds.y, bounds.width, bounds.height, previewColor); | ||
| 146 | afa.attach(target, scaleMode, hAlign, vAlign, crop, minWidth, maxWidth, minHeight, maxHeight, calculateVisible); | ||
| 147 | return afa; | ||
| 148 | } | ||
| 149 | |||
| 150 | /** | ||
| 151 | * Attaches a DisplayObject, causing it to automatically scale to fit the area in one of the | ||
| 152 | * following ScaleModes: <code>STRETCH, PROPORTIONAL_INSIDE, PROPORTIONAL_OUTSIDE, NONE, WIDTH_ONLY,</code> | ||
| 153 | * or <code>HEIGHT_ONLY</code>. Horizontally and vertically align the object within the area as well. | ||
| 154 | * When the area resizes, all attached DisplayObjects will automatically be moved/scaled accordingly. | ||
| 155 | * | ||
| 156 | * @param target The DisplayObject to attach and scale/stretch to fit within the area. | ||
| 157 | * @param scaleMode Determines how the target should be scaled to fit the area. ScaleMode choices are: <code>STRETCH, PROPORTIONAL_INSIDE, PROPORTIONAL_OUTSIDE, NONE, WIDTH_ONLY,</code> or <code>HEIGHT_ONLY</code>. | ||
| 158 | * @param hAlign Horizontal alignment of the target inside the area. AlignMode choices are: <code>LEFT</code>, <code>CENTER</code>, and <code>RIGHT</code>. | ||
| 159 | * @param vAlign Vertical alignment of the target inside the area. AlignMode choices are: <code>TOP</code>, <code>CENTER</code>, and <code>BOTTOM</code>. | ||
| 160 | * @param crop If true, a mask will be created and added to the display list so that the target will be cropped wherever it exceeds the bounds of the AutoFitArea. | ||
| 161 | * @param minWidth Minimum width to which the target is allowed to scale | ||
| 162 | * @param maxWidth Maximum width to which the target is allowed to scale | ||
| 163 | * @param minHeight Minimum height to which the target is allowed to scale | ||
| 164 | * @param maxHeight Maximum height to which the target is allowed to scale | ||
| 165 | * @param calculateVisible If true, only the visible portions of the target will be taken into account when determining its position and scale which can be useful for objects that have masks applied (otherwise, Flash reports their width/height and getBounds() values including the masked portions). Setting <code>calculateVisible</code> to <code>true</code> degrades performance, so only use it when absolutely necessary. | ||
| 166 | * @param customAspectRatio Normally if you set the <code>scaleMode</code> to <code>PROPORTIONAL_INSIDE</code> or <code>PROPORTIONAL_OUTSIDE</code>, its native (unscaled) dimensions will be used to determine the proportions (aspect ratio), but if you prefer to define a custom width-to-height ratio, use <code>customAspectRatio</code>. For example, if an item is 100 pixels wide and 50 pixels tall at its native size, the aspect ratio would be 100/50 or 2. If, however, you want it to be square (a 1-to-1 ratio), the <code>customAspectRatio</code> would be 1. | ||
| 167 | */ | ||
| 168 | public function attach(target:DisplayObject, scaleMode:String="proportionalInside", hAlign:String="center", vAlign:String="center", crop:Boolean=false, minWidth:Number=0, maxWidth:Number=999999999, minHeight:Number=0, maxHeight:Number=999999999, calculateVisible:Boolean=false, customAspectRatio:Number=NaN):void { | ||
| 169 | if (target.parent != _parent) { | ||
| 170 | throw new Error("The parent of the DisplayObject " + target.name + " added to AutoFitArea " + this.name + " doesn't share the same parent."); | ||
| 171 | } | ||
| 172 | release(target); | ||
| 173 | _rootItem = new AutoFitItem(target, scaleMode, hAlign, vAlign, minWidth, maxWidth, minHeight, maxHeight, calculateVisible, customAspectRatio, _rootItem); | ||
| 174 | if (crop) { | ||
| 175 | var shape:Shape = new Shape(); | ||
| 176 | var bounds:Rectangle = this.getBounds(this); | ||
| 177 | shape.graphics.beginFill(_previewColor, 1); | ||
| 178 | shape.graphics.drawRect(bounds.x, bounds.y, bounds.width, bounds.height); | ||
| 179 | shape.graphics.endFill(); | ||
| 180 | shape.visible = false; | ||
| 181 | _parent.addChild(shape); | ||
| 182 | _rootItem.mask = shape; | ||
| 183 | target.mask = shape; | ||
| 184 | } | ||
| 185 | if (_preview) { | ||
| 186 | this.preview = true; | ||
| 187 | } | ||
| 188 | update(null); | ||
| 189 | } | ||
| 190 | |||
| 191 | /** | ||
| 192 | * Releases control of an attached DisplayObject. | ||
| 193 | * | ||
| 194 | * @param target The DisplayObject to release | ||
| 195 | * @return if the target was found and released, this value will be true. If the target isn't attached, it will be false. | ||
| 196 | */ | ||
| 197 | public function release(target:DisplayObject):Boolean { | ||
| 198 | var item:AutoFitItem = getItem(target); | ||
| 199 | if (item == null) { | ||
| 200 | return false; | ||
| 201 | } | ||
| 202 | if (item.mask != null) { | ||
| 203 | if (item.mask.parent) { | ||
| 204 | item.mask.parent.removeChild(item.mask); | ||
| 205 | } | ||
| 206 | target.mask = null; | ||
| 207 | item.mask = null; | ||
| 208 | } | ||
| 209 | if (item.next) { | ||
| 210 | item.next.prev = item.prev; | ||
| 211 | } | ||
| 212 | if (item.prev) { | ||
| 213 | item.prev.next = item.next; | ||
| 214 | } else if (item == _rootItem) { | ||
| 215 | _rootItem = item.next; | ||
| 216 | } | ||
| 217 | item.next = item.prev = null; | ||
| 218 | return true; | ||
| 219 | } | ||
| 220 | |||
| 221 | /** | ||
| 222 | * Returns an Array of all attached DisplayObjects. | ||
| 223 | * | ||
| 224 | * @return An array of all attached objects | ||
| 225 | */ | ||
| 226 | public function getAttachedObjects():Array { | ||
| 227 | var a:Array = []; | ||
| 228 | var cnt:uint = 0; | ||
| 229 | var item:AutoFitItem = _rootItem; | ||
| 230 | while (item) { | ||
| 231 | a[cnt++] = item.target; | ||
| 232 | item = item.next; | ||
| 233 | } | ||
| 234 | return a; | ||
| 235 | } | ||
| 236 | |||
| 237 | /** @private **/ | ||
| 238 | protected function getItem(target:DisplayObject):AutoFitItem { | ||
| 239 | var item:AutoFitItem = _rootItem; | ||
| 240 | while (item) { | ||
| 241 | if (item.target == target) { | ||
| 242 | return item; | ||
| 243 | } | ||
| 244 | item = item.next; | ||
| 245 | } | ||
| 246 | return null; | ||
| 247 | } | ||
| 248 | |||
| 249 | |||
| 250 | /** | ||
| 251 | * Forces the area to update, making any necessary adjustments to the scale/position of attached objects. | ||
| 252 | * @param event An optional event (which is unused internally) - this makes it possible to have an ENTER_FRAME or some other listener call this method if, for example, you want the AutoFitArea to constantly update and make any adjustments to attached objects that may have resized or been manually moved. | ||
| 253 | **/ | ||
| 254 | public function update(event:Event=null):void { | ||
| 255 | //create local variables to speed things up | ||
| 256 | var width:Number = this.width; | ||
| 257 | var height:Number = this.height; | ||
| 258 | var x:Number = this.x; | ||
| 259 | var y:Number = this.y; | ||
| 260 | var matrix:Matrix = this.transform.matrix; | ||
| 261 | |||
| 262 | var item:AutoFitItem = _rootItem; | ||
| 263 | var w:Number, h:Number, target:DisplayObject, bounds:Rectangle, tRatio:Number, scaleMode:String, ratio:Number, angle:Number, sin:Number, cos:Number, m:Matrix, mScale:Number, mPrev:Matrix; | ||
| 264 | while (item) { | ||
| 265 | target = item.target; | ||
| 266 | scaleMode = item.scaleMode; | ||
| 267 | |||
| 268 | if (scaleMode != ScaleMode.NONE) { | ||
| 269 | |||
| 270 | bounds = (item.calculateVisible) ? (item.bounds = getVisibleBounds(target, target)) : target.getBounds(target); | ||
| 271 | tRatio = (item.hasCustomRatio) ? item.aspectRatio : bounds.width / bounds.height; | ||
| 272 | |||
| 273 | m = target.transform.matrix; | ||
| 274 | if (m.b != 0 || m.a == 0 || m.d == 0) { | ||
| 275 | //if the width/height is zero, we cannot accurately measure the angle. | ||
| 276 | if (m.a == 0 || m.d == 0) { | ||
| 277 | m = target.transform.matrix = item.matrix; | ||
| 278 | } else { | ||
| 279 | //inline operations are about 10 times faster than doing item.matrix = m.clone(); | ||
| 280 | mPrev = item.matrix; | ||
| 281 | mPrev.a = m.a; | ||
| 282 | mPrev.b = m.b; | ||
| 283 | mPrev.c = m.c; | ||
| 284 | mPrev.d = m.d; | ||
| 285 | mPrev.tx = m.tx; | ||
| 286 | mPrev.ty = m.ty; | ||
| 287 | } | ||
| 288 | angle = Math.atan2(m.b, m.a); | ||
| 289 | if (m.a < 0 && m.d >= 0) { | ||
| 290 | if (angle <= 0) { | ||
| 291 | angle += Math.PI; | ||
| 292 | } else { | ||
| 293 | angle -= Math.PI; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | sin = Math.sin(angle); | ||
| 297 | if (sin < 0) { | ||
| 298 | sin = -sin; | ||
| 299 | } | ||
| 300 | cos = Math.cos(angle); | ||
| 301 | if (cos < 0) { | ||
| 302 | cos = -cos; | ||
| 303 | } | ||
| 304 | tRatio = (tRatio * cos + sin) / (tRatio * sin + cos); | ||
| 305 | } | ||
| 306 | |||
| 307 | w = (width > item.maxWidth) ? item.maxWidth : (width < item.minWidth) ? item.minWidth : width; | ||
| 308 | h = (height > item.maxHeight) ? item.maxHeight : (height < item.minHeight) ? item.minHeight : height; | ||
| 309 | ratio = w / h; | ||
| 310 | |||
| 311 | if ((tRatio < ratio && scaleMode == ScaleMode.PROPORTIONAL_INSIDE) || (tRatio > ratio && scaleMode == ScaleMode.PROPORTIONAL_OUTSIDE)) { | ||
| 312 | w = h * tRatio; | ||
| 313 | if (w > item.maxWidth) { | ||
| 314 | w = item.maxWidth; | ||
| 315 | h = w / tRatio; | ||
| 316 | } else if (w < item.minWidth) { | ||
| 317 | w = item.minWidth; | ||
| 318 | h = w / tRatio; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | if ((tRatio > ratio && scaleMode == ScaleMode.PROPORTIONAL_INSIDE) || (tRatio < ratio && scaleMode == ScaleMode.PROPORTIONAL_OUTSIDE)) { | ||
| 322 | h = w / tRatio; | ||
| 323 | if (h > item.maxHeight) { | ||
| 324 | h = item.maxHeight; | ||
| 325 | w = h * tRatio; | ||
| 326 | } else if (h < item.minHeight) { | ||
| 327 | h = item.minHeight; | ||
| 328 | w = h * tRatio; | ||
| 329 | } | ||
| 330 | } | ||
| 331 | if (scaleMode != ScaleMode.HEIGHT_ONLY) { | ||
| 332 | if (item.calculateVisible) { | ||
| 333 | item.setVisibleWidth(w); | ||
| 334 | } else if (m.b != 0) { | ||
| 335 | mScale = w / target.width; | ||
| 336 | m.a *= mScale; | ||
| 337 | m.c *= mScale; | ||
| 338 | target.transform.matrix = m; | ||
| 339 | } else { | ||
| 340 | target.width = w; | ||
| 341 | } | ||
| 342 | } | ||
| 343 | if (scaleMode != ScaleMode.WIDTH_ONLY) { | ||
| 344 | if (item.calculateVisible) { | ||
| 345 | item.setVisibleHeight(h); | ||
| 346 | } else if (m.b != 0) { | ||
| 347 | mScale = h / target.height; | ||
| 348 | m.d *= mScale; | ||
| 349 | m.b *= mScale; | ||
| 350 | target.transform.matrix = m; | ||
| 351 | } else { | ||
| 352 | target.height = h; | ||
| 353 | } | ||
| 354 | } | ||
| 355 | |||
| 356 | } | ||
| 357 | |||
| 358 | bounds = (item.calculateVisible) ? getVisibleBounds(target, _parent) : target.getBounds(_parent); | ||
| 359 | |||
| 360 | if (item.hAlign == AlignMode.LEFT) { | ||
| 361 | target.x += (x - bounds.x); | ||
| 362 | } else if (item.hAlign == AlignMode.CENTER) { | ||
| 363 | target.x += (x - bounds.x) + ((width - target.width) * 0.5); | ||
| 364 | } else { | ||
| 365 | target.x += (x - bounds.x) + (width - target.width); | ||
| 366 | } | ||
| 367 | |||
| 368 | if (item.vAlign == AlignMode.TOP) { | ||
| 369 | target.y += (y - bounds.y); | ||
| 370 | } else if (item.vAlign == AlignMode.CENTER) { | ||
| 371 | target.y += (y - bounds.y) + ((height - target.height) * 0.5); | ||
| 372 | } else { | ||
| 373 | target.y += (y - bounds.y) + (height - target.height); | ||
| 374 | } | ||
| 375 | |||
| 376 | if (item.mask) { | ||
| 377 | item.mask.transform.matrix = matrix; | ||
| 378 | } | ||
| 379 | |||
| 380 | item = item.next; | ||
| 381 | } | ||
| 382 | |||
| 383 | if (_hasListener) { | ||
| 384 | dispatchEvent(new Event(Event.CHANGE)); | ||
| 385 | } | ||
| 386 | } | ||
| 387 | |||
| 388 | /** | ||
| 389 | * Enables the area's tween mode; normally, any changes to the area's transform properties like | ||
| 390 | * <code>x, y, scaleX, scaleY, width,</code> or <code>height</code> will force an immediate | ||
| 391 | * <code>update()</code> call but when the area is in tween mode, that automatic <code>update()</code> | ||
| 392 | * is suspended. This effects perfomance because if, for example, you tween the area's <code>x, y, width</code>, | ||
| 393 | * and <code>height</code> properties simultaneously, <code>update()</code> would get called 4 times | ||
| 394 | * each frame (once for each property) even though it only really needs to be called once after all | ||
| 395 | * properties were updated inside the tween. So to maximize performance during a tween, it is best | ||
| 396 | * to use the tween's <code>onStart</code> to call <code>enableTweenMode()</code> at the beginning | ||
| 397 | * of the tween, use the tween's <code>onUpdate</code> to call the area's <code>update()</code> method, | ||
| 398 | * and then the tween's <code>onComplete</code> to call <code>disableTweenMode()</code> like so:<br /><br /><code> | ||
| 399 | * | ||
| 400 | * TweenLite.to(myArea, 3, {x:100, y:50, width:300, height:250, onStart:myArea.enableTweenMode, onUpdate:myArea.update, onComplete:myArea.disableTweenMode});</code> | ||
| 401 | **/ | ||
| 402 | public function enableTweenMode():void { | ||
| 403 | _tweenMode = true; | ||
| 404 | } | ||
| 405 | |||
| 406 | /** | ||
| 407 | * Disables the area's tween mode; normally, any changes to the area's transform properties like | ||
| 408 | * <code>x, y, scaleX, scaleY, width,</code> or <code>height</code> will force an immediate | ||
| 409 | * <code>update()</code> call but when the area is in tween mode, that automatic <code>update()</code> | ||
| 410 | * is suspended. This effects perfomance because if, for example, you tween the area's <code>x, y, width</code>, | ||
| 411 | * and <code>height</code> properties simultaneously, <code>update()</code> would get called 4 times | ||
| 412 | * each frame (once for each property) even though it only really needs to be called once after all | ||
| 413 | * properties were updated inside the tween. So to maximize performance during a tween, it is best | ||
| 414 | * to use the tween's <code>onStart</code> to call <code>enableTweenMode()</code> at the beginning | ||
| 415 | * of the tween, use the tween's <code>onUpdate</code> to call the area's <code>update()</code> method, | ||
| 416 | * and then the tween's <code>onComplete</code> to call <code>disableTweenMode()</code> like so:<br /><br /><code> | ||
| 417 | * | ||
| 418 | * TweenLite.to(myArea, 3, {x:100, y:50, width:300, height:250, onStart:myArea.enableTweenMode, onUpdate:myArea.update, onComplete:myArea.disableTweenMode});</code> | ||
| 419 | **/ | ||
| 420 | public function disableTweenMode():void { | ||
| 421 | _tweenMode = false; | ||
| 422 | } | ||
| 423 | |||
| 424 | /** | ||
| 425 | * Allows you to add an <code>Event.CHANGE</code> event listener. | ||
| 426 | * | ||
| 427 | * @param type Event type (<code>Event.CHANGE</code>) | ||
| 428 | * @param listener Listener function | ||
| 429 | * @param useCapture useCapture | ||
| 430 | * @param priority Priority level | ||
| 431 | * @param useWeakReference Use weak references | ||
| 432 | */ | ||
| 433 | override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void { | ||
| 434 | _hasListener = true; | ||
| 435 | super.addEventListener(type, listener, useCapture, priority, useWeakReference); | ||
| 436 | } | ||
| 437 | |||
| 438 | /** Destroys the instance by releasing all DisplayObjects, setting preview to false, and nulling references to the parent, ensuring that garbage collection isn't hindered. **/ | ||
| 439 | public function destroy():void { | ||
| 440 | if (_preview) { | ||
| 441 | this.preview = false; | ||
| 442 | } | ||
| 443 | var nxt:AutoFitItem; | ||
| 444 | var item:AutoFitItem = _rootItem; | ||
| 445 | while (item) { | ||
| 446 | nxt = item.next; | ||
| 447 | release(item.target); | ||
| 448 | item = nxt; | ||
| 449 | } | ||
| 450 | if (_bd != null) { | ||
| 451 | _bd.dispose(); | ||
| 452 | _bd = null; | ||
| 453 | } | ||
| 454 | _parent = null; | ||
| 455 | } | ||
| 456 | |||
| 457 | /** @private For objects with masks, the only way to accurately report the bounds of the visible areas is to use BitmapData. **/ | ||
| 458 | protected static function getVisibleBounds(target:DisplayObject, targetCoordinateSpace:DisplayObject):Rectangle { | ||
| 459 | if (_bd == null) { | ||
| 460 | _bd = new BitmapData(2800, 2800, true, 0x00FFFFFF); | ||
| 461 | } | ||
| 462 | _bd.fillRect(_rect, 0x00FFFFFF); | ||
| 463 | _matrix.tx = _matrix.ty = 0; | ||
| 464 | var offset:Rectangle = target.getBounds(targetCoordinateSpace); | ||
| 465 | var m:Matrix = (targetCoordinateSpace == target) ? _matrix : target.transform.matrix; | ||
| 466 | m.tx -= offset.x; | ||
| 467 | m.ty -= offset.y; | ||
| 468 | _bd.draw(target, m, null, "normal", _rect, false); | ||
| 469 | var bounds:Rectangle = _bd.getColorBoundsRect(0xFF000000, 0x00000000, false); | ||
| 470 | bounds.x += offset.x; | ||
| 471 | bounds.y += offset.y; | ||
| 472 | return bounds; | ||
| 473 | } | ||
| 474 | |||
| 475 | /** @private **/ | ||
| 476 | protected function _redraw(color:uint):void { | ||
| 477 | _previewColor = color; | ||
| 478 | var g:Graphics = this.graphics; | ||
| 479 | g.clear(); | ||
| 480 | g.beginFill(_previewColor, 1); | ||
| 481 | g.drawRect(0, 0, _width, _height); | ||
| 482 | g.endFill(); | ||
| 483 | } | ||
| 484 | |||
| 485 | //---- GETTERS / SETTERS --------------------------------------------------------------------------- | ||
| 486 | |||
| 487 | /** @inheritDoc **/ | ||
| 488 | override public function set x(value:Number):void { | ||
| 489 | super.x = value; | ||
| 490 | if (!_tweenMode) { | ||
| 491 | update(); | ||
| 492 | } | ||
| 493 | } | ||
| 494 | |||
| 495 | /** @inheritDoc **/ | ||
| 496 | override public function set y(value:Number):void { | ||
| 497 | super.y = value; | ||
| 498 | if (!_tweenMode) { | ||
| 499 | update(); | ||
| 500 | } | ||
| 501 | } | ||
| 502 | |||
| 503 | /** @inheritDoc **/ | ||
| 504 | override public function set width(value:Number):void { | ||
| 505 | super.width = value; | ||
| 506 | if (!_tweenMode) { | ||
| 507 | update(); | ||
| 508 | } | ||
| 509 | } | ||
| 510 | |||
| 511 | /** @inheritDoc **/ | ||
| 512 | override public function set height(value:Number):void { | ||
| 513 | super.height = value; | ||
| 514 | if (!_tweenMode) { | ||
| 515 | update(); | ||
| 516 | } | ||
| 517 | } | ||
| 518 | |||
| 519 | /** @inheritDoc **/ | ||
| 520 | override public function set scaleX(value:Number):void { | ||
| 521 | super.scaleX = value; | ||
| 522 | update(); | ||
| 523 | } | ||
| 524 | |||
| 525 | /** @inheritDoc **/ | ||
| 526 | override public function set scaleY(value:Number):void { | ||
| 527 | super.scaleY = value; | ||
| 528 | update(); | ||
| 529 | } | ||
| 530 | |||
| 531 | /** @inheritDoc **/ | ||
| 532 | override public function set rotation(value:Number):void { | ||
| 533 | trace("Warning: AutoFitArea instances should not be rotated."); | ||
| 534 | } | ||
| 535 | |||
| 536 | /** The preview color with which the area should be filled, making it easy to visualize on the stage. You will not see this color unless you set <code>preview</code> to true or manually add the area to the display list with addChild(). **/ | ||
| 537 | public function get previewColor():uint { | ||
| 538 | return _previewColor; | ||
| 539 | } | ||
| 540 | public function set previewColor(value:uint):void { | ||
| 541 | _redraw(value); | ||
| 542 | } | ||
| 543 | |||
| 544 | /** To see a visual representation of the area on the screen, set <code>preview</code> to <code>true</code>. Doing so will add the area to the display list behind any DisplayObjects that have been attached. **/ | ||
| 545 | public function get preview():Boolean { | ||
| 546 | return _preview; | ||
| 547 | } | ||
| 548 | public function set preview(value:Boolean):void { | ||
| 549 | _preview = value; | ||
| 550 | if (this.parent == _parent) { | ||
| 551 | _parent.removeChild(this); | ||
| 552 | } | ||
| 553 | if (value) { | ||
| 554 | var level:uint = (_rootItem == null) ? 0 : 999999999; | ||
| 555 | var index:uint; | ||
| 556 | var item:AutoFitItem = _rootItem; | ||
| 557 | while (item) { | ||
| 558 | if (item.target.parent == _parent) { | ||
| 559 | index = _parent.getChildIndex(item.target); | ||
| 560 | if (index < level) { | ||
| 561 | level = index; | ||
| 562 | } | ||
| 563 | } | ||
| 564 | item = item.next; | ||
| 565 | } | ||
| 566 | _parent.addChildAt(this, level); | ||
| 567 | this.visible = true; | ||
| 568 | } | ||
| 569 | } | ||
| 570 | |||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | import flash.display.BitmapData; | ||
| 575 | import flash.display.DisplayObject; | ||
| 576 | import flash.display.Shape; | ||
| 577 | import flash.geom.Matrix; | ||
| 578 | import flash.geom.Rectangle; | ||
| 579 | |||
| 580 | internal class AutoFitItem { | ||
| 581 | public var target:DisplayObject; | ||
| 582 | public var scaleMode:String; | ||
| 583 | public var hAlign:String; | ||
| 584 | public var vAlign:String; | ||
| 585 | public var minWidth:Number; | ||
| 586 | public var maxWidth:Number; | ||
| 587 | public var minHeight:Number; | ||
| 588 | public var maxHeight:Number; | ||
| 589 | public var aspectRatio:Number; | ||
| 590 | public var mask:Shape; | ||
| 591 | public var matrix:Matrix; | ||
| 592 | public var hasCustomRatio:Boolean; | ||
| 593 | |||
| 594 | public var next:AutoFitItem; | ||
| 595 | public var prev:AutoFitItem; | ||
| 596 | |||
| 597 | public var calculateVisible:Boolean; | ||
| 598 | public var bounds:Rectangle; | ||
| 599 | |||
| 600 | /** @private **/ | ||
| 601 | public function AutoFitItem(target:DisplayObject, scaleMode:String, hAlign:String, vAlign:String, minWidth:Number, maxWidth:Number, minHeight:Number, maxHeight:Number, calculateVisible:Boolean, customAspectRatio:Number, next:AutoFitItem) { | ||
| 602 | this.target = target; | ||
| 603 | this.scaleMode = scaleMode; | ||
| 604 | this.hAlign = hAlign; | ||
| 605 | this.vAlign = vAlign; | ||
| 606 | this.minWidth = minWidth; | ||
| 607 | this.maxWidth = maxWidth; | ||
| 608 | this.minHeight = minHeight; | ||
| 609 | this.maxHeight = maxHeight; | ||
| 610 | this.matrix = target.transform.matrix; | ||
| 611 | this.calculateVisible = calculateVisible; | ||
| 612 | if (!isNaN(customAspectRatio)) { | ||
| 613 | this.aspectRatio = customAspectRatio; | ||
| 614 | this.hasCustomRatio = true; | ||
| 615 | } | ||
| 616 | if (next) { | ||
| 617 | next.prev = this; | ||
| 618 | this.next = next; | ||
| 619 | } | ||
| 620 | } | ||
| 621 | |||
| 622 | /** @private **/ | ||
| 623 | public function setVisibleWidth(value:Number):void { | ||
| 624 | var m:Matrix = this.target.transform.matrix; | ||
| 625 | if ((m.a == 0 && m.c == 0) || (m.d == 0 && m.b == 0)) { | ||
| 626 | m.a = this.matrix.a; | ||
| 627 | m.c = this.matrix.c; | ||
| 628 | } | ||
| 629 | var curWidth:Number = (m.a < 0) ? -m.a * this.bounds.width : m.a * this.bounds.width; | ||
| 630 | curWidth += (m.c < 0) ? -m.c * this.bounds.height : m.c * this.bounds.height; | ||
| 631 | if (curWidth != 0) { | ||
| 632 | var scale:Number = value / curWidth; | ||
| 633 | m.a *= scale; | ||
| 634 | m.c *= scale; | ||
| 635 | this.target.transform.matrix = m; | ||
| 636 | if (value != 0) { | ||
| 637 | this.matrix = m; | ||
| 638 | } | ||
| 639 | } | ||
| 640 | } | ||
| 641 | |||
| 642 | /** @private **/ | ||
| 643 | public function setVisibleHeight(value:Number):void { | ||
| 644 | var m:Matrix = this.target.transform.matrix; | ||
| 645 | if ((m.a == 0 && m.c == 0) || (m.d == 0 && m.b == 0)) { | ||
| 646 | m.b = this.matrix.b; | ||
| 647 | m.d = this.matrix.d; | ||
| 648 | } | ||
| 649 | var curHeight:Number = (m.b < 0) ? -m.b * this.bounds.width : m.b * this.bounds.width; | ||
| 650 | curHeight += (m.d < 0) ? -m.d * this.bounds.height : m.d * this.bounds.height; | ||
| 651 | if (curHeight != 0) { | ||
| 652 | var scale:Number = value / curHeight; | ||
| 653 | m.b *= scale; | ||
| 654 | m.d *= scale; | ||
| 655 | this.target.transform.matrix = m; | ||
| 656 | if (value != 0) { | ||
| 657 | this.matrix = m; | ||
| 658 | } | ||
| 659 | } | ||
| 660 | } | ||
| 661 | |||
| 662 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.04 | ||
| 3 | * DATE: 2010-03-06 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://blog.greensock.com/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.layout { | ||
| 8 | /** | ||
| 9 | * Provides constants for defining how objects should scale/stretch to fit within an area (like a <code>LiquidArea</code> or <code>AutoFitArea</code>). <br /><br /> | ||
| 10 | * | ||
| 11 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 12 | * | ||
| 13 | * @author Jack Doyle, jack@greensock.com | ||
| 14 | */ | ||
| 15 | public class ScaleMode { | ||
| 16 | |||
| 17 | /** Stretches the object to fill the area completely in terms of both width and height. This mode does <b>NOT</b> concern itself with preserving the object's original aspect ratio (proportions). **/ | ||
| 18 | public static const STRETCH:String = "stretch"; | ||
| 19 | /** Stretches the object's width to fill the area horizontally, but does not affect its height **/ | ||
| 20 | public static const WIDTH_ONLY:String = "widthOnly"; | ||
| 21 | /** Stretches the object's height to fill the area vertically, but does not affect its width **/ | ||
| 22 | public static const HEIGHT_ONLY:String = "heightOnly"; | ||
| 23 | /** Scales the object proportionally to completely fill the area, allowing portions of it to exceed the bounds when its aspect ratio doesn't match the area's. For example, if the area is 100x50 and the DisplayObject is natively 200x200, it will scale it down to 100x100 meaning it will exceed the bounds of the area vertically. **/ | ||
| 24 | public static const PROPORTIONAL_OUTSIDE:String = "proportionalOutside"; | ||
| 25 | /** Scales the object proportionally to fit inside the area (its edges will never exceed the bounds of the area). For example, if the area is 100x50 and the DisplayObject is natively 200x200, it will scale it down to 50x50 meaning it will not fill the area horizontally, but it will vertically. **/ | ||
| 26 | public static const PROPORTIONAL_INSIDE:String = "proportionalInside"; | ||
| 27 | /** Does not scale the object at all **/ | ||
| 28 | public static const NONE:String = "none"; | ||
| 29 | |||
| 30 | } | ||
| 31 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.3 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import flash.events.Event; | ||
| 9 | import flash.text.StyleSheet; | ||
| 10 | |||
| 11 | /** Dispatched when the loader's <code>httpStatus</code> value changes. **/ | ||
| 12 | [Event(name="httpStatus", type="com.greensock.events.LoaderEvent")] | ||
| 13 | /** | ||
| 14 | * Loads StyleSheet (CSS) data. <br /><br /> | ||
| 15 | * | ||
| 16 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 17 | * The following special properties can be passed into the CSSLoader constructor via its <code>vars</code> | ||
| 18 | * parameter which can be either a generic object or a <code><a href="data/CSSLoaderVars.html">CSSLoaderVars</a></code> object:<br /> | ||
| 19 | * <ul> | ||
| 20 | * <li><strong> name : String</strong> - A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 21 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 22 | * <li><strong> noCache : Boolean</strong> - If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally)</li> | ||
| 23 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 24 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this CSSLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:CSSLoader = new CSSLoader("styles.css", {name:"styles", requireWithRoot:this.root});</code></li> | ||
| 25 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 26 | * | ||
| 27 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 28 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 29 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 30 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 31 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 32 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 33 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 34 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 35 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 36 | * </ul><br /> | ||
| 37 | * | ||
| 38 | * <strong>Note:</strong> Using a <code><a href="data/CSSLoaderVars.html">CSSLoaderVars</a></code> instance | ||
| 39 | * instead of a generic object to define your <code>vars</code> is a bit more verbose but provides | ||
| 40 | * code hinting and improved debugging because it enforces strict data typing. Use whichever one you prefer.<br /><br /> | ||
| 41 | * | ||
| 42 | * <code>content</code> data type: <strong><code>flash.text.StyleSheet</code></strong><br /><br /> | ||
| 43 | * | ||
| 44 | * @example Example AS3 code:<listing version="3.0"> | ||
| 45 | import com.greensock.loading.~~; | ||
| 46 | import com.greensock.events.LoaderEvent; | ||
| 47 | import import flash.text.StyleSheet; | ||
| 48 | |||
| 49 | //create a CSSLoader | ||
| 50 | var loader:CSSLoader = new CSSLoader("css/styles.css", {name:"myCSS", requireWithRoot:this.root, estimatedBytes:900}); | ||
| 51 | |||
| 52 | //begin loading | ||
| 53 | loader.load(); | ||
| 54 | |||
| 55 | //Or you could put the CSSLoader into a LoaderMax. Create one first... | ||
| 56 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 57 | |||
| 58 | //append the CSSLoader and several other loaders | ||
| 59 | queue.append( loader ); | ||
| 60 | queue.append( new SWFLoader("swf/main.swf", {name:"mainSWF", estimatedBytes:4800}) ); | ||
| 61 | queue.append( new ImageLoader("img/photo1.jpg", {name:"photo1", estimatedBytes:3500}) ); | ||
| 62 | |||
| 63 | //start loading | ||
| 64 | queue.load(); | ||
| 65 | |||
| 66 | function progressHandler(event:LoaderEvent):void { | ||
| 67 | trace("progress: " + event.target.progress); | ||
| 68 | } | ||
| 69 | |||
| 70 | function completeHandler(event:LoaderEvent):void { | ||
| 71 | myTextField.styleSheet = LoaderMax.getContent("myCSS"); | ||
| 72 | trace("load complete."); | ||
| 73 | } | ||
| 74 | |||
| 75 | function errorHandler(event:LoaderEvent):void { | ||
| 76 | trace("error occured with " + event.target + ": " + event.text); | ||
| 77 | } | ||
| 78 | |||
| 79 | </listing> | ||
| 80 | * | ||
| 81 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 82 | * | ||
| 83 | * @see com.greensock.loading.data.CSSLoaderVars | ||
| 84 | * | ||
| 85 | * @author Jack Doyle, jack@greensock.com | ||
| 86 | */ | ||
| 87 | public class CSSLoader extends DataLoader { | ||
| 88 | /** @private **/ | ||
| 89 | private static var _classActivated:Boolean = _activateClass("CSSLoader", CSSLoader, "css"); | ||
| 90 | |||
| 91 | /** | ||
| 92 | * Constructor | ||
| 93 | * | ||
| 94 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content. | ||
| 95 | * @param vars An object containing optional configuration details. For example: <code>new CSSLoader("css/styles.css", {name:"myCSS", onComplete:completeHandler, onProgress:progressHandler})</code>.<br /><br /> | ||
| 96 | * | ||
| 97 | * The following special properties can be passed into the constructor via the <code>vars</code> parameter | ||
| 98 | * which can be either a generic object or a <code><a href="data/CSSLoaderVars.html">CSSLoaderVars</a></code> object:<br /> | ||
| 99 | * <ul> | ||
| 100 | * <li><strong> name : String</strong> - A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 101 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 102 | * <li><strong> noCache : Boolean</strong> - If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally)</li> | ||
| 103 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 104 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this CSSLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:CSSLoader = new CSSLoader("styles.css", {name:"styles", requireWithRoot:this.root});</code></li> | ||
| 105 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 106 | * | ||
| 107 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 108 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 109 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 110 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 111 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 112 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 113 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 114 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 115 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 116 | * </ul> | ||
| 117 | * @see com.greensock.loading.data.CSSLoaderVars | ||
| 118 | */ | ||
| 119 | public function CSSLoader(urlOrRequest:*, vars:Object=null) { | ||
| 120 | super(urlOrRequest, vars); | ||
| 121 | _type = "CSSLoader"; | ||
| 122 | } | ||
| 123 | |||
| 124 | |||
| 125 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 126 | |||
| 127 | /** @private **/ | ||
| 128 | override protected function _receiveDataHandler(event:Event):void { | ||
| 129 | var style:StyleSheet = _content = new StyleSheet(); | ||
| 130 | style.parseCSS(_loader.data); | ||
| 131 | super._completeHandler(event); | ||
| 132 | } | ||
| 133 | |||
| 134 | |||
| 135 | } | ||
| 136 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.3 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import com.greensock.loading.core.LoaderItem; | ||
| 9 | import com.greensock.loading.LoaderStatus; | ||
| 10 | |||
| 11 | import flash.events.Event; | ||
| 12 | import flash.events.ProgressEvent; | ||
| 13 | import flash.net.URLLoader; | ||
| 14 | |||
| 15 | /** Dispatched when the loader's <code>httpStatus</code> value changes. **/ | ||
| 16 | [Event(name="httpStatus", type="com.greensock.events.LoaderEvent")] | ||
| 17 | /** Dispatched when the loader experiences a SECURITY_ERROR while loading or auditing its size. **/ | ||
| 18 | [Event(name="securityError", type="com.greensock.events.LoaderEvent")] | ||
| 19 | /** | ||
| 20 | * Loads generic data which can be text (the default), binary data, or URL-encoded variables. <br /><br /> | ||
| 21 | * | ||
| 22 | * If the <code>format</code> vars property is "text", the <code>content</code> will be a String containing the text of the loaded file.<br /><br /> | ||
| 23 | * If the <code>format</code> vars property is "binary", the <code>content</code> will be a <code>ByteArray</code> object containing the raw binary data.<br /><br /> | ||
| 24 | * If the <code>format</code> vars property is "variables", the <code>content</code> will be a <code>URLVariables</code> object containing the URL-encoded variables<br /><br /> | ||
| 25 | * | ||
| 26 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 27 | * The following special properties can be passed into the DataLoader constructor via its <code>vars</code> | ||
| 28 | * parameter which can be either a generic object or a <code><a href="data/DataLoaderVars.html">DataLoaderVars</a></code> object:<br /> | ||
| 29 | * <ul> | ||
| 30 | * <li><strong> name : String</strong> - A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 31 | * <li><strong> format : String</strong> - Controls whether the downloaded data is received as text (<code>"text"</code>), raw binary data (<code>"binary"</code>), or URL-encoded variables (<code>"variables"</code>). </li> | ||
| 32 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 33 | * <li><strong> noCache : Boolean</strong> - If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally)</li> | ||
| 34 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 35 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this DataLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:DataLoader = new DataLoader("text.txt", {name:"myText", requireWithRoot:this.root});</code></li> | ||
| 36 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 37 | * | ||
| 38 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 39 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 40 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 41 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 42 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 43 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 44 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 45 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 46 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 47 | * </ul><br /> | ||
| 48 | * | ||
| 49 | * <strong>Note:</strong> Using a <code><a href="data/DataLoaderVars.html">DataLoaderVars</a></code> instance | ||
| 50 | * instead of a generic object to define your <code>vars</code> is a bit more verbose but provides | ||
| 51 | * code hinting and improved debugging because it enforces strict data typing. Use whichever one you prefer.<br /><br /> | ||
| 52 | * | ||
| 53 | * @example Example AS3 code:<listing version="3.0"> | ||
| 54 | import com.greensock.loading.~~; | ||
| 55 | import com.greensock.events.LoaderEvent; | ||
| 56 | import flash.utils.ByteArray; | ||
| 57 | import flash.net.URLVariables; | ||
| 58 | |||
| 59 | //create a DataLoader for loading text (the default format) | ||
| 60 | var loader:DataLoader = new DataLoader("assets/data.txt", {name:"myText", requireWithRoot:this.root, estimatedBytes:900}); | ||
| 61 | |||
| 62 | //start loading | ||
| 63 | loader.load(); | ||
| 64 | |||
| 65 | //Or you could put the DataLoader into a LoaderMax. Create one first... | ||
| 66 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 67 | |||
| 68 | //append the DataLoader and several other loaders | ||
| 69 | queue.append( loader ); | ||
| 70 | queue.append( new DataLoader("assets/variables.txt", {name:"myVariables", format:"variables"}) ); | ||
| 71 | queue.append( new DataLoader("assets/image1.png", {name:"myBinary", format:"binary", estimatedBytes:3500}) ); | ||
| 72 | |||
| 73 | //start loading the LoaderMax queue | ||
| 74 | queue.load(); | ||
| 75 | |||
| 76 | function progressHandler(event:LoaderEvent):void { | ||
| 77 | trace("progress: " + event.target.progress); | ||
| 78 | } | ||
| 79 | |||
| 80 | function completeHandler(event:LoaderEvent):void { | ||
| 81 | var text:String = LoaderMax.getContent("myText"); | ||
| 82 | var variables:URLVariables = LoaderMax.getContent("myVariables"); | ||
| 83 | var binary:ByteArray = LoaderMax.getContent("myBinary"); | ||
| 84 | trace("complete. myText: " + text + ", myVariables.var1: " + variables.var1 + ", myBinary.length: " + binary.length); | ||
| 85 | } | ||
| 86 | |||
| 87 | function errorHandler(event:LoaderEvent):void { | ||
| 88 | trace("error occured with " + event.target + ": " + event.text); | ||
| 89 | } | ||
| 90 | </listing> | ||
| 91 | * | ||
| 92 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 93 | * | ||
| 94 | * @see com.greensock.loading.data.DataLoaderVars | ||
| 95 | * | ||
| 96 | * @author Jack Doyle, jack@greensock.com | ||
| 97 | */ | ||
| 98 | public class DataLoader extends LoaderItem { | ||
| 99 | /** @private **/ | ||
| 100 | private static var _classActivated:Boolean = _activateClass("DataLoader", DataLoader, "txt,js"); | ||
| 101 | /** @private **/ | ||
| 102 | protected var _loader:URLLoader; | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Constructor | ||
| 106 | * | ||
| 107 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content. | ||
| 108 | * @param vars An object containing optional configuration details. For example: <code>new DataLoader("text/data.txt", {name:"data", onComplete:completeHandler, onProgress:progressHandler})</code>.<br /><br /> | ||
| 109 | * | ||
| 110 | * The following special properties can be passed into the constructor via the <code>vars</code> parameter | ||
| 111 | * which can be either a generic object or a <code><a href="data/DataLoaderVars.html">DataLoaderVars</a></code> object:<br /> | ||
| 112 | * <ul> | ||
| 113 | * <li><strong> name : String</strong> - A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 114 | * <li><strong> format : String</strong> - Controls whether the downloaded data is received as text (<code>"text"</code>), raw binary data (<code>"binary"</code>), or URL-encoded variables (<code>"variables"</code>). </li> | ||
| 115 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 116 | * <li><strong> noCache : Boolean</strong> - If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally)</li> | ||
| 117 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 118 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this DataLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:DataLoader = new DataLoader("text.txt", {name:"myText", requireWithRoot:this.root});</code></li> | ||
| 119 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 120 | * | ||
| 121 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 122 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 123 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 124 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 125 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 126 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 127 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 128 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 129 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 130 | * </ul> | ||
| 131 | * @see com.greensock.loading.data.DataLoaderVars | ||
| 132 | */ | ||
| 133 | public function DataLoader(urlOrRequest:*, vars:Object=null) { | ||
| 134 | super(urlOrRequest, vars); | ||
| 135 | _type = "DataLoader"; | ||
| 136 | _loader = new URLLoader(null); | ||
| 137 | if ("format" in this.vars) { | ||
| 138 | _loader.dataFormat = String(this.vars.format); | ||
| 139 | } | ||
| 140 | _loader.addEventListener(ProgressEvent.PROGRESS, _progressHandler, false, 0, true); | ||
| 141 | _loader.addEventListener(Event.COMPLETE, _receiveDataHandler, false, 0, true); | ||
| 142 | _loader.addEventListener("ioError", _failHandler, false, 0, true); | ||
| 143 | _loader.addEventListener("securityError", _failHandler, false, 0, true); | ||
| 144 | _loader.addEventListener("httpStatus", _httpStatusHandler, false, 0, true); | ||
| 145 | } | ||
| 146 | |||
| 147 | /** @private **/ | ||
| 148 | override protected function _load():void { | ||
| 149 | _prepRequest(); | ||
| 150 | _loader.load(_request); | ||
| 151 | } | ||
| 152 | |||
| 153 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 154 | override protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 155 | if (_status == LoaderStatus.LOADING) { | ||
| 156 | try { | ||
| 157 | _loader.close(); | ||
| 158 | } catch (error:Error) { | ||
| 159 | |||
| 160 | } | ||
| 161 | } | ||
| 162 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 163 | } | ||
| 164 | |||
| 165 | |||
| 166 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 167 | |||
| 168 | /** @private Don't use _completeHandler so that subclasses can set _content differently and still call super._completeHandler() (otherwise setting _content in the _completeHandler would always override the _content previously set in sublcasses). **/ | ||
| 169 | protected function _receiveDataHandler(event:Event):void { | ||
| 170 | _content = _loader.data; | ||
| 171 | super._completeHandler(event); | ||
| 172 | } | ||
| 173 | |||
| 174 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 175 | |||
| 176 | |||
| 177 | |||
| 178 | } | ||
| 179 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.3 | ||
| 3 | * DATE: 2010-08-10 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import com.greensock.loading.core.DisplayObjectLoader; | ||
| 9 | |||
| 10 | import flash.display.Bitmap; | ||
| 11 | import flash.events.Event; | ||
| 12 | /** | ||
| 13 | * Loads an image file (png, jpg, or gif) and automatically applies smoothing by default. <br /><br /> | ||
| 14 | * | ||
| 15 | * The ImageLoader's <code>content</code> refers to a <code>ContentDisplay</code> (Sprite) that | ||
| 16 | * is created immediately so that you can position/scale/rotate it or add ROLL_OVER/ROLL_OUT/CLICK listeners | ||
| 17 | * before (or while) the image loads. Use the ImageLoader's <code>content</code> property to get the ContentDisplay | ||
| 18 | * Sprite, or use the <code>rawContent</code> property to get the actual Bitmap. If a <code>container</code> | ||
| 19 | * is defined in the <code>vars</code> object, the ContentDisplay will immediately be added to that container). <br /><br /> | ||
| 20 | * | ||
| 21 | * If you define a <code>width</code> and <code>height</code>, it will draw a rectangle | ||
| 22 | * in the ContentDisplay so that interactive events fire appropriately (rollovers, etc.) and width/height/bounds | ||
| 23 | * get reported accurately. This rectangle is invisible by default, but you can control its color and alpha | ||
| 24 | * with the <code>bgColor</code> and <code>bgAlpha</code> properties. When the image loads, it will be | ||
| 25 | * added to the ContentDisplay at index 0 with <code>addChildAt()</code> and scaled to fit the width/height | ||
| 26 | * according to the <code>scaleMode</code>. These are all optional features - you do not need to define a | ||
| 27 | * <code>width</code> or <code>height</code> in which case the image will load at its native size. | ||
| 28 | * See the list below for all the special properties that can be passed through the <code>vars</code> | ||
| 29 | * parameter but don't let the list overwhelm you - these are all optional and they are intended to make | ||
| 30 | * your job as a developer much easier.<br /><br /> | ||
| 31 | * | ||
| 32 | * By default, the ImageLoader will attempt to load the image in a way that allows full script | ||
| 33 | * access. However, if a security error is thrown because the image is being loaded from another | ||
| 34 | * domain and the appropriate crossdomain.xml file isn't in place to grant access, the ImageLoader | ||
| 35 | * will automatically adjust the default LoaderContext so that it falls back to the more restricted | ||
| 36 | * mode which will have the following effect: | ||
| 37 | * <ul> | ||
| 38 | * <li>A <code>LoaderEvent.SCRIPT_ACCESS_DENIED</code> event will be dispatched and the <code>scriptAccessDenied</code> property of the ImageLoader will be set to <code>true</code>. You can check this value before performing any restricted operations on the content like BitmapData.draw().</li> | ||
| 39 | * <li>The ImageLoader's <code>rawContent</code> property will be a <code>Loader</code> instance instead of a Bitmap.</li> | ||
| 40 | * <li>The <code>smoothing</code> property will <strong>not</strong> be set to <code>true</code>.</li> | ||
| 41 | * <li>BitmapData operations like draw() will not be able to be performed on the image.</li> | ||
| 42 | * </ul> | ||
| 43 | * | ||
| 44 | * To maximize the likelihood of your image loading without any security problems, consider taking the following steps: | ||
| 45 | * <ul> | ||
| 46 | * <li><strong>Use a crossdomain.xml file </strong> - See Adobe's docs for details, but here is an example that grants full access (put this in a crossdomain.xml file that is at the root of the remote domain):<br /> | ||
| 47 | * <?xml version="1.0" encoding="utf-8"?><br /> | ||
| 48 | * <cross-domain-policy><br /> | ||
| 49 | * <allow-access-from domain="~~" /><br /> | ||
| 50 | * </cross-domain-policy></li> | ||
| 51 | * <li>In the embed code of any HTML wrapper, set <code>AllowScriptAccess</code> to <code>"always"</code></li> | ||
| 52 | * </ul><br /> | ||
| 53 | * | ||
| 54 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 55 | * The following special properties can be passed into the ImageLoader constructor via its <code>vars</code> | ||
| 56 | * parameter which can be either a generic object or an <code><a href="data/ImageLoaderVars.html">ImageLoaderVars</a></code> object:<br /> | ||
| 57 | * <ul> | ||
| 58 | * <li><strong> name : String</strong> - A name that is used to identify the ImageLoader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 59 | * <li><strong> container : DisplayObjectContainer</strong> - A DisplayObjectContainer into which the <code>ContentDisplay</code> Sprite should be added immediately.</li> | ||
| 60 | * <li><strong> smoothing : Boolean</strong> - When <code>smoothing</code> is <code>true</code> (the default), smoothing will be enabled for the image which typically leads to much better scaling results (otherwise the image can look crunchy/jagged). If your image is loaded from another domain where the appropriate crossdomain.xml file doesn't grant permission, Flash will not allow smoothing to be enabled (it's a security restriction).</li> | ||
| 61 | * <li><strong> width : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 62 | * <li><strong> height : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 63 | * <li><strong> centerRegistration : Boolean </strong> - If <code>true</code>, the registration point will be placed in the center of the ContentDisplay which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center.</li> | ||
| 64 | * <li><strong> scaleMode : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded image will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 65 | * <ul> | ||
| 66 | * <li><code>"stretch"</code> (the default) - The image will fill the width/height exactly.</li> | ||
| 67 | * <li><code>"proportionalInside"</code> - The image will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 68 | * <li><code>"proportionalOutside"</code> - The image will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height.</li> | ||
| 69 | * <li><code>"widthOnly"</code> - Only the width of the image will be adjusted to fit.</li> | ||
| 70 | * <li><code>"heightOnly"</code> - Only the height of the image will be adjusted to fit.</li> | ||
| 71 | * <li><code>"none"</code> - No scaling of the image will occur.</li> | ||
| 72 | * </ul></li> | ||
| 73 | * <li><strong> hAlign : String </strong> - When a <code>width</code> and <code>height</code> is defined, the <code>hAlign</code> determines how the image is horizontally aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 74 | * <ul> | ||
| 75 | * <li><code>"center"</code> (the default) - The image will be centered horizontally in the area</li> | ||
| 76 | * <li><code>"left"</code> - The image will be aligned with the left side of the area</li> | ||
| 77 | * <li><code>"right"</code> - The image will be aligned with the right side of the area</li> | ||
| 78 | * </ul></li> | ||
| 79 | * <li><strong> vAlign : String </strong> - When a <code>width</code> and <code>height</code> is defined, the <code>vAlign</code> determines how the image is vertically aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 80 | * <ul> | ||
| 81 | * <li><code>"center"</code> (the default) - The image will be centered vertically in the area</li> | ||
| 82 | * <li><code>"top"</code> - The image will be aligned with the top of the area</li> | ||
| 83 | * <li><code>"bottom"</code> - The image will be aligned with the bottom of the area</li> | ||
| 84 | * </ul></li> | ||
| 85 | * <li><strong> crop : Boolean</strong> - When a <code>width</code> and <code>height</code> are defined, setting <code>crop</code> to <code>true</code> will cause the image to be cropped within that area (by applying a <code>scrollRect</code> for maximum performance). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> or <code>"none"</code> so that any parts of the image that exceed the dimensions defined by <code>width</code> and <code>height</code> are visually chopped off. Use the <code>hAlign</code> and <code>vAlign</code> special properties to control the vertical and horizontal alignment within the cropped area.</li> | ||
| 86 | * <li><strong> x : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>x</code> property (for positioning on the stage).</li> | ||
| 87 | * <li><strong> y : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>y</code> property (for positioning on the stage).</li> | ||
| 88 | * <li><strong> scaleX : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleX</code> property.</li> | ||
| 89 | * <li><strong> scaleY : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleY</code> property.</li> | ||
| 90 | * <li><strong> rotation : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>rotation</code> property.</li> | ||
| 91 | * <li><strong> alpha : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>alpha</code> property.</li> | ||
| 92 | * <li><strong> visible : Boolean</strong> - Sets the <code>ContentDisplay</code>'s <code>visible</code> property.</li> | ||
| 93 | * <li><strong> blendMode : String</strong> - Sets the <code>ContentDisplay</code>'s <code>blendMode</code> property.</li> | ||
| 94 | * <li><strong> bgColor : uint </strong> - When a <code>width</code> and <code>height</code> are defined, a rectangle will be drawn inside the <code>ContentDisplay</code> Sprite immediately in order to ease the development process. It is transparent by default, but you may define a <code>bgAlpha</code> if you prefer.</li> | ||
| 95 | * <li><strong> bgAlpha : Number </strong> - Controls the alpha of the rectangle that is drawn when a <code>width</code> and <code>height</code> are defined.</li> | ||
| 96 | * <li><strong> context : LoaderContext</strong> - To control whether or not a policy file is checked (which is required if you're loading an image from another domain and you want to use it in BitmapData operations), define a <code>LoaderContext</code> object. By default, the policy file <strong>will</strong> be checked when running remotely, so make sure the appropriate crossdomain.xml file is in place. See Adobe's <code>LoaderContext</code> documentation for details and precautions. </li> | ||
| 97 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader will be inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 98 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 99 | * <li><strong> noCache : Boolean</strong> - If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally)</li> | ||
| 100 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this ImageLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:ImageLoader = new ImageLoader("photo1.jpg", {name:"image1", requireWithRoot:this.root});</code></li> | ||
| 101 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 102 | * | ||
| 103 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 104 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 105 | * <li><strong> onInit : Function</strong> - A handler function for <code>LoaderEvent.INIT</code> events which are called when the image has downloaded and has been placed into the ContentDisplay Sprite. Make sure your onInit function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 106 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 107 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 108 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 109 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 110 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 111 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 112 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 113 | * <li><strong> onSecurityError : Function</strong> - A handler function for <code>LoaderEvent.SECURITY_ERROR</code> events which onError handles as well, so you can use that as more of a catch-all whereas onSecurityError is specifically for SECURITY_ERROR events. Make sure your onSecurityError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 114 | * <li><strong> onScriptAccessDenied : Function</strong> - A handler function for <code>LoaderEvent.SCRIPT_ACCESS_DENIED</code> events which are dispatched when the image is loaded from another domain and no crossdomain.xml is in place to grant full script access for things like smoothing or BitmapData manipulation. You can also check the loader's <code>scriptAccessDenied</code> property after the image has loaded. Make sure your function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 115 | * </ul><br /> | ||
| 116 | * | ||
| 117 | * <strong>Note:</strong> Using a <code><a href="data/ImageLoaderVars.html">ImageLoaderVars</a></code> instance | ||
| 118 | * instead of a generic object to define your <code>vars</code> is a bit more verbose but provides | ||
| 119 | * code hinting and improved debugging because it enforces strict data typing. Use whichever one you prefer.<br /><br /> | ||
| 120 | * | ||
| 121 | * <code>content</code> data type: <strong><code>com.greensock.loading.display.ContentDisplay</code></strong> (a Sprite). | ||
| 122 | * When the image has finished loading, the <code>rawContent</code> will be added to the <code>ContentDisplay</code> Sprite | ||
| 123 | * at index 0 using <code>addChildAt()</code>. <code>rawContent</code> will be a <code>flash.display.Bitmap</code> unless | ||
| 124 | * unless script access is denied in which case it will be a <code>flash.display.Loader</code> (to avoid security errors).<br /><br /> | ||
| 125 | * | ||
| 126 | * @example Example AS3 code:<listing version="3.0"> | ||
| 127 | import com.greensock.~~; | ||
| 128 | import com.greensock.events.LoaderEvent; | ||
| 129 | import com.greensock.loading.~~; | ||
| 130 | |||
| 131 | //create an ImageLoader: | ||
| 132 | var loader:ImageLoader = new ImageLoader("img/photo1.jpg", {name:"photo1", container:this, x:180, y:100, width:200, height:150, scaleMode:"proportionalInside", centerRegistration:true, onComplete:onImageLoad}); | ||
| 133 | |||
| 134 | //begin loading | ||
| 135 | loader.load(); | ||
| 136 | |||
| 137 | //when the image loads, fade it in from alpha:0 using TweenLite | ||
| 138 | function onImageLoad(event:LoaderEvent):void { | ||
| 139 | TweenLite.from(event.target.content, 1, {alpha:0}); | ||
| 140 | } | ||
| 141 | |||
| 142 | //Or you could put the ImageLoader into a LoaderMax. Create one first... | ||
| 143 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 144 | |||
| 145 | //append the ImageLoader and several other loaders | ||
| 146 | queue.append( loader ); | ||
| 147 | queue.append( new XMLLoader("xml/doc.xml", {name:"xmlDoc", estimatedBytes:425}) ); | ||
| 148 | queue.append( new SWFLoader("swf/main.swf", {name:"mainClip", estimatedBytes:3000, container:this, autoPlay:false}) ); | ||
| 149 | |||
| 150 | //start loading | ||
| 151 | queue.load(); | ||
| 152 | |||
| 153 | function progressHandler(event:LoaderEvent):void { | ||
| 154 | trace("progress: " + queue.progress); | ||
| 155 | } | ||
| 156 | |||
| 157 | function completeHandler(event:LoaderEvent):void { | ||
| 158 | trace(event.target + " is complete!"); | ||
| 159 | } | ||
| 160 | |||
| 161 | function errorHandler(event:LoaderEvent):void { | ||
| 162 | trace("error occured with " + event.target + ": " + event.text); | ||
| 163 | } | ||
| 164 | |||
| 165 | </listing> | ||
| 166 | * <strong>NOTES / TIPS:</strong><br /> | ||
| 167 | * <ul> | ||
| 168 | * <li>You will not see the image unless you either manually add it to the display list in your onComplete handler or simply use the <code>container</code> special property (see above).</li> | ||
| 169 | * </ul><br /><br /> | ||
| 170 | * | ||
| 171 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 172 | * | ||
| 173 | * @see com.greensock.loading.data.ImageLoaderVars | ||
| 174 | * | ||
| 175 | * @author Jack Doyle, jack@greensock.com | ||
| 176 | */ | ||
| 177 | public class ImageLoader extends DisplayObjectLoader { | ||
| 178 | /** @private **/ | ||
| 179 | private static var _classActivated:Boolean = _activateClass("ImageLoader", ImageLoader, "jpg,jpeg,png,gif,bmp"); | ||
| 180 | /** | ||
| 181 | * Constructor | ||
| 182 | * | ||
| 183 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content | ||
| 184 | * @param vars An object containing optional configuration details. For example: <code>new ImageLoader("img/photo1.jpg", {name:"photo1", container:this, x:100, y:50, alpha:0, onComplete:completeHandler, onProgress:progressHandler})</code>.<br /><br /> | ||
| 185 | * | ||
| 186 | * The following special properties can be passed into the constructor via the <code>vars</code> parameter | ||
| 187 | * which can be either a generic object or an <code><a href="data/ImageLoaderVars.html">ImageLoaderVars</a></code> object:<br /> | ||
| 188 | * <ul> | ||
| 189 | * <li><strong> name : String</strong> - A name that is used to identify the ImageLoader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 190 | * <li><strong> container : DisplayObjectContainer</strong> - A DisplayObjectContainer into which the <code>ContentDisplay</code> Sprite should be added immediately.</li> | ||
| 191 | * <li><strong> smoothing : Boolean</strong> - When <code>smoothing</code> is <code>true</code> (the default), smoothing will be enabled for the image which typically leads to much better scaling results (otherwise the image can look crunchy/jagged). If your image is loaded from another domain where the appropriate crossdomain.xml file doesn't grant permission, Flash will not allow smoothing to be enabled (it's a security restriction).</li> | ||
| 192 | * <li><strong> width : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 193 | * <li><strong> height : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 194 | * <li><strong> centerRegistration : Boolean </strong> - if <code>true</code>, the registration point will be placed in the center of the ContentDisplay which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center.</li> | ||
| 195 | * <li><strong> scaleMode : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded image will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 196 | * <ul> | ||
| 197 | * <li><code>"stretch"</code> (the default) - The image will fill the width/height exactly.</li> | ||
| 198 | * <li><code>"proportionalInside"</code> - The image will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 199 | * <li><code>"proportionalOutside"</code> - The image will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height.</li> | ||
| 200 | * <li><code>"widthOnly"</code> - Only the width of the image will be adjusted to fit.</li> | ||
| 201 | * <li><code>"heightOnly"</code> - Only the height of the image will be adjusted to fit.</li> | ||
| 202 | * <li><code>"none"</code> - No scaling of the image will occur.</li> | ||
| 203 | * </ul></li> | ||
| 204 | * <li><strong> hAlign : String </strong> - When a <code>width</code> and <code>height</code> is defined, the <code>hAlign</code> determines how the image is horizontally aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 205 | * <ul> | ||
| 206 | * <li><code>"center"</code> (the default) - The image will be centered horizontally in the area</li> | ||
| 207 | * <li><code>"left"</code> - The image will be aligned with the left side of the area</li> | ||
| 208 | * <li><code>"right"</code> - The image will be aligned with the right side of the area</li> | ||
| 209 | * </ul></li> | ||
| 210 | * <li><strong> vAlign : String </strong> - When a <code>width</code> and <code>height</code> is defined, the <code>vAlign</code> determines how the image is vertically aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 211 | * <ul> | ||
| 212 | * <li><code>"center"</code> (the default) - The image will be centered vertically in the area</li> | ||
| 213 | * <li><code>"top"</code> - The image will be aligned with the top of the area</li> | ||
| 214 | * <li><code>"bottom"</code> - The image will be aligned with the bottom of the area</li> | ||
| 215 | * </ul></li> | ||
| 216 | * <li><strong> crop : Boolean</strong> - When a <code>width</code> and <code>height</code> are defined, setting <code>crop</code> to <code>true</code> will cause the image to be cropped within that area (by applying a <code>scrollRect</code> for maximum performance). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> or <code>"none"</code> so that any parts of the image that exceed the dimensions defined by <code>width</code> and <code>height</code> are visually chopped off. Use the <code>hAlign</code> and <code>vAlign</code> special properties to control the vertical and horizontal alignment within the cropped area.</li> | ||
| 217 | * <li><strong> x : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>x</code> property (for positioning on the stage).</li> | ||
| 218 | * <li><strong> y : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>y</code> property (for positioning on the stage).</li> | ||
| 219 | * <li><strong> scaleX : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleX</code> property.</li> | ||
| 220 | * <li><strong> scaleY : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleY</code> property.</li> | ||
| 221 | * <li><strong> rotation : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>rotation</code> property.</li> | ||
| 222 | * <li><strong> alpha : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>alpha</code> property.</li> | ||
| 223 | * <li><strong> visible : Boolean</strong> - Sets the <code>ContentDisplay</code>'s <code>visible</code> property.</li> | ||
| 224 | * <li><strong> blendMode : String</strong> - Sets the <code>ContentDisplay</code>'s <code>blendMode</code> property.</li> | ||
| 225 | * <li><strong> bgColor : uint </strong> - When a <code>width</code> and <code>height</code> are defined, a rectangle will be drawn inside the <code>ContentDisplay</code> Sprite immediately in order to ease the development process. It is transparent by default, but you may define a <code>bgAlpha</code> if you prefer.</li> | ||
| 226 | * <li><strong> bgAlpha : Number </strong> - Controls the alpha of the rectangle that is drawn when a <code>width</code> and <code>height</code> are defined.</li> | ||
| 227 | * <li><strong> context : LoaderContext</strong> - To control whether or not a policy file is checked (which is required if you're loading an image from another domain and you want to use it in BitmapData operations), define a <code>LoaderContext</code> object. By default, the policy file <strong>will</strong> be checked when running remotely, so make sure the appropriate crossdomain.xml file is in place. See Adobe's <code>LoaderContext</code> documentation for details and precautions. </li> | ||
| 228 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader will be inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 229 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 230 | * <li><strong> noCache : Boolean</strong> - If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally)</li> | ||
| 231 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this ImageLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:ImageLoader = new ImageLoader("photo1.jpg", {name:"image1", requireWithRoot:this.root});</code></li> | ||
| 232 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 233 | * | ||
| 234 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 235 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 236 | * <li><strong> onInit : Function</strong> - A handler function for <code>LoaderEvent.INIT</code> events which are called when the image has downloaded and has been placed into the ContentDisplay Sprite. Make sure your onInit function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 237 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 238 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 239 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 240 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 241 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 242 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 243 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 244 | * <li><strong> onSecurityError : Function</strong> - A handler function for <code>LoaderEvent.SECURITY_ERROR</code> events which onError handles as well, so you can use that as more of a catch-all whereas onSecurityError is specifically for SECURITY_ERROR events. Make sure your onSecurityError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 245 | * <li><strong> onScriptAccessDenied : Function</strong> - A handler function for <code>LoaderEvent.SCRIPT_ACCESS_DENIED</code> events which are dispatched when the image is loaded from another domain and no crossdomain.xml is in place to grant full script access for things like smoothing or BitmapData manipulation. You can also check the loader's <code>scriptAccessDenied</code> property after the image has loaded. Make sure your function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 246 | * </ul> | ||
| 247 | * @see com.greensock.loading.data.ImageLoaderVars | ||
| 248 | */ | ||
| 249 | public function ImageLoader(urlOrRequest:*, vars:Object=null) { | ||
| 250 | super(urlOrRequest, vars); | ||
| 251 | _type = "ImageLoader"; | ||
| 252 | } | ||
| 253 | |||
| 254 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 255 | |||
| 256 | /** @private **/ | ||
| 257 | override protected function _initHandler(event:Event):void { | ||
| 258 | _determineScriptAccess(); | ||
| 259 | if (!_scriptAccessDenied) { | ||
| 260 | _content = Bitmap(_loader.content); | ||
| 261 | _content.smoothing = Boolean(this.vars.smoothing != false); | ||
| 262 | } else { | ||
| 263 | _content = _loader; | ||
| 264 | } | ||
| 265 | super._initHandler(event); | ||
| 266 | } | ||
| 267 | |||
| 268 | } | ||
| 269 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.46 | ||
| 3 | * DATE: 2010-09-15 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.LoaderMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import com.greensock.events.LoaderEvent; | ||
| 9 | import com.greensock.loading.core.LoaderCore; | ||
| 10 | import com.greensock.loading.core.LoaderItem; | ||
| 11 | |||
| 12 | import flash.display.DisplayObject; | ||
| 13 | import flash.events.ErrorEvent; | ||
| 14 | import flash.events.Event; | ||
| 15 | import flash.events.ProgressEvent; | ||
| 16 | import flash.utils.Dictionary; | ||
| 17 | |||
| 18 | /** Dispatched when any child of the LoaderMax instance starts loading. So if a LoaderMax contains 5 loaders, the CHILD_OPEN event will be dispatched 5 times during the course of the LoaderMax's load. This can occur even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 19 | [Event(name="childOpen", type="com.greensock.events.LoaderEvent")] | ||
| 20 | /** Dispatched when any child of the LoaderMax instance dispatches a PROGRESS event. This can occur even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 21 | [Event(name="childProgress", type="com.greensock.events.LoaderEvent")] | ||
| 22 | /** Dispatched when any child of the LoaderMax instance completes. So if a LoaderMax contains 5 loaders, the CHILD_COMPLETE event will be dispatched 5 times during the course of the LoaderMax's load. This can occur even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 23 | [Event(name="childComplete", type="com.greensock.events.LoaderEvent")] | ||
| 24 | /** Dispatched when any child of the LoaderMax instance fails to load. This occurs even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 25 | [Event(name="childFail", type="com.greensock.events.LoaderEvent")] | ||
| 26 | /** Dispatched when any child of the LoaderMax instance dispatches a CANCEL event which could occur when another child is prioritized in the queue or when the LoaderMax is canceled while loading the child. CHILD_CANCEL can be dispatched even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 27 | [Event(name="childCancel", type="com.greensock.events.LoaderEvent")] | ||
| 28 | /** Dispatched when any child of the LoaderMax instance dispatches a SCRIPT_ACCESS_DENIED event. This can occur even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 29 | [Event(name="scriptAccessDenied", type="com.greensock.events.LoaderEvent")] | ||
| 30 | /** Dispatched when any child of the LoaderMax instance dispatches an HTTP_STATUS event. This can occur even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 31 | [Event(name="httpStatus", type="com.greensock.events.LoaderEvent")] | ||
| 32 | /** Dispatched when any child of the LoaderMax instance dispatches an IO_ERROR event. This can occur even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 33 | [Event(name="ioError", type="com.greensock.events.LoaderEvent")] | ||
| 34 | /** Dispatched when any child of the LoaderMax instance dispatches a SECURITY_ERROR event. This can occur even if the LoaderMax itself isn't in the process of loading (because load() or prioritize() could have been called directly on a child loader) **/ | ||
| 35 | [Event(name="securityError", type="com.greensock.events.LoaderEvent")] | ||
| 36 | /** | ||
| 37 | * In its simplest form, a LoaderMax provides a way to group a sequence of loaders together and | ||
| 38 | * report their progress as a whole. It is essentially a queue of loaders. But there are many other | ||
| 39 | * conveniences that the LoaderMax system delivers: | ||
| 40 | * <ul> | ||
| 41 | * <li><strong> Integration of loaders inside subloaded swfs</strong> - With most other systems, if you subload a swf, the loader will only concern itself with the swf file's bytes but what if that swf must subload other content like XML, images, and/or other swf files before it should be considered fully loaded? LoaderMax can elegantly handle the sub-subloads as deep as they go. You can link any loader and/or LoaderMax with a swf's root (using the <code>requireWithRoot</code> vars property) so that when you subload it into another Flash application, the parent SWFLoader automatically factors the nested loaders into its overall loading progress! It won't dispatch its <code>COMPLETE</code> event until they have finished as well. </li> | ||
| 42 | * <li><strong> Automatic parsing of LoaderMax-related nodes inside XML</strong> - The XMLLoader class automatically looks for LoaderMax-related nodes like <code><LoaderMax>, <ImageLoader>, <SWFLoader>, <XMLLoader>, <VideoLoader>, <DataLoader>, <CSSLoader>, <MP3Loader></code>, etc. in XML files that it loads, and if any are found it will create the necessary instances and then begin loading the ones that had a <code>load="true"</code> attribute, automatically integrating their progress into the XMLLoader's overall progress and it won't dispatch a <code>COMPLETE</code> event until the XML-driven loaders have finished as well.</li> | ||
| 43 | * <li><strong> Tight file size</strong> - Many other systems are 16-24k+ even if you're just loading text, but LoaderMax can be as little as <strong>7k</strong> (depending on which loader types you use).</li> | ||
| 44 | * <li><strong> A common set of properties and methods among all loaders</strong> - Every loader type (XMLLoader, SWFLoader, ImageLoader, MP3Loader, CSSLoader, VideoLoader, LoaderMax, etc.) all share common <code>content, name, status, loadTime, paused, bytesLoaded, bytesTotal,</code> and <code>progress</code> properties as well as methods like <code>load(), pause(), resume(), prioritize(), unload(), cancel(), auditSize()</code> and <code>dispose()</code> delivering a touch of polymorphism sweetness.</li> | ||
| 45 | * <li><strong> Nest LoaderMax instances inside other LoaderMax instances as deeply as you want.</strong> - This makes complex queues simple. Need to know when the first 3 loaders have finished loading inside a 10-loader queue? Just put those 3 into their own LoaderMax that has an onComplete and nest that LoaderMax inside your main LoaderMax queue. </li> | ||
| 46 | * <li><strong> Set a width/height for an ImageLoader, SWFLoader, or VideoLoader and when it loads, the image/swf/video will automatically scale to fit</strong> using any of the following scaleModes: "stretch", "proportionalInside", "proportionalOutside", "widthOnly", or "heightOnly". Even crop the image/swf/video with <code>crop:true</code>.</li> | ||
| 47 | * <li><strong> Conveniences like auto smoothing of images, centering their registration point, noCache, setting initial x, y, scaleX, scaleY, rotation, alpha, and blendMode properties, optional autoPlay for mp3s, swfs, and videos, and more.</strong></li> | ||
| 48 | * <li><strong> Works around common Flash hassles/bugs</strong> - LoaderMax implements workarounds for things like garbage collection headaches with subloaded swfs, images, and NetStreams as well as problems with subloaded swfs that use TLF.</li> | ||
| 49 | * <li><strong> Find loaders and content by name or url</strong> - Every loader has a <code>name</code> property which you can use to uniquely identify it. Feed a name or URL to the static <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods to quickly get the associated loader or content.</li> | ||
| 50 | * <li><strong> A single loader can belong to multiple LoaderMax instances</strong></li> | ||
| 51 | * <li><strong> Accurate progress reporting</strong> - For maximum performance, set an <code>estimatedBytes</code> for each loader or allow LoaderMax's <code>auditSize</code> feature to automatically preload just enough of each child loader's content to determine its <code>bytesTotal</code>, making progress reporting on large queues very accurate.</li> | ||
| 52 | * <li><strong> prioritize() a loader anytime</strong> - Kick an object to the top of all LoaderMax queues to which it belongs, immediately supplanting the top spot in each one.</li> | ||
| 53 | * <li><strong> A robust event system</strong></li> | ||
| 54 | * <li><strong> Define an alternateURL for any loader</strong> - If the original <code>url</code> fails to load, it will automatically switch to the <code>alternateURL</code> and try again.</li> | ||
| 55 | * <li><strong> Set up multiple event listeners in one line</strong> - Add listeners like onComplete, onProgress, onError, etc. via the constructor like <code>new LoaderMax({name:"mainQueue", onComplete:completeHandler, onProgress:progressHandler, onError:errorHandler});</code></li> | ||
| 56 | * <li><strong> maxConnections</strong> - Set the maximum number of simultaneous connections for each LoaderMax instance (default is 2). This can speed up overall loading times.</li> | ||
| 57 | * <li><strong> pause()/resume()</strong> - no queue loading solution would be complete without the ability to pause()/resume() anytime.</li> | ||
| 58 | * <li><strong> Flex friendly </strong> - Simply change the <code>LoaderMax.contentDisplayClass</code> to <code>FlexContentDisplay</code> and then ImageLoaders, SWFLoaders, and VideoLoaders will return <code>content</code> wrapped in a UIComponent.</li> | ||
| 59 | * </ul><br /> | ||
| 60 | * | ||
| 61 | * @example Example AS3 code:<listing version="3.0"> | ||
| 62 | import com.greensock.~~; | ||
| 63 | import com.greensock.loading.~~; | ||
| 64 | import com.greensock.events.LoaderEvent; | ||
| 65 | import com.greensock.loading.display.~~; | ||
| 66 | |||
| 67 | //create a LoaderMax named "mainQueue" and set up onProgress, onComplete and onError listeners | ||
| 68 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 69 | |||
| 70 | //append several loaders | ||
| 71 | queue.append( new XMLLoader("xml/data.xml", {name:"xmlDoc", alternateURL:"http://otherserver.com/data.xml"}) ); | ||
| 72 | queue.append( new ImageLoader("img/photo1.jpg", {name:"photo1", estimatedBytes:2400, container:this, alpha:0, width:250, height:150, scaleMode:"proportionalInside"}) ); | ||
| 73 | queue.append( new SWFLoader("swf/main.swf", {name:"mainClip", estimatedBytes:3000, container:this, x:250, autoPlay:false}) ); | ||
| 74 | |||
| 75 | //add a loader to the top of the queue using prepend() | ||
| 76 | queue.prepend( new MP3Loader("mp3/audio.mp3", {name:"audio", repeat:100, autoPlay:true}) ); | ||
| 77 | |||
| 78 | //prioritize the loader named "photo1" | ||
| 79 | LoaderMax.prioritize("photo1"); //same as LoaderMax.getLoader("photo1").prioritize(); | ||
| 80 | |||
| 81 | //start loading | ||
| 82 | queue.load(); | ||
| 83 | |||
| 84 | function progressHandler(event:LoaderEvent):void { | ||
| 85 | trace("progress: " + event.target.progress); | ||
| 86 | } | ||
| 87 | |||
| 88 | function completeHandler(event:LoaderEvent):void { | ||
| 89 | var image:ContentDisplay = LoaderMax.getContent("photo1"); | ||
| 90 | TweenLite.to(image, 1, {alpha:1, y:100}); | ||
| 91 | trace(event.target + " is complete!"); | ||
| 92 | } | ||
| 93 | |||
| 94 | function errorHandler(event:LoaderEvent):void { | ||
| 95 | trace("error occured with " + event.target + ": " + event.text); | ||
| 96 | } | ||
| 97 | </listing> | ||
| 98 | * | ||
| 99 | * LoaderMax will automatically skip over any child loaders in the queue that are already complete. By default | ||
| 100 | * it will also skip any that have failed or are paused (you can change this behavior with the <code>skipFailed</code> | ||
| 101 | * and <code>skipPaused</code> special properties). To flush the content and force a full reload, simply <code>unload()</code> | ||
| 102 | * first or use the <code>flushContent</code> parameter in <code>load()</code> like <code>load(true)</code>.<br /><br /> | ||
| 103 | * | ||
| 104 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 105 | * The following special properties can be passed into the LoaderMax constructor via the <code>vars</code> | ||
| 106 | * parameter which can be either a generic object or a <code><a href="data/LoaderMaxVars.html">LoaderMaxVars</a></code> object:<br /> | ||
| 107 | * <ul> | ||
| 108 | * <li><strong> name : String</strong> - A name that is used to identify the LoaderMax instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 109 | * <li><strong> auditSize : Boolean</strong> - By default, when the LoaderMax begins to load it quickly loops through its children and if it finds any that don't have an <code>estimatedBytes</code> defined, it will briefly open a URLStream in order to attempt to determine its <code>bytesTotal</code>, immediately closing the URLStream once the value has been determined. This causes a brief delay initially, but greatly improves the accuracy of the <code>progress</code> and <code>bytesTotal</code> values. Set <code>auditSize</code> to <code>false</code> to prevent the LoaderMax from auditing its childrens' size (it is <code>true</code> by default). For maximum performance, it is best to define an <code>estimatedBytes</code> value for as many loaders as possible to avoid the delay caused by audits. When the LoaderMax audits an XMLLoader, it cannot recognize loaders that will be created from the XML data nor can it recognize loaders inside subloaded swf files from a SWFLoader (it would take far too long to load sufficient data for that - audits should be as fast as possible). If you do not set an appropriate <code>estimatedSize</code> for XMLLoaders or SWFLoaders that contain LoaderMax loaders, you'll notice that the parent LoaderMax's <code>progress</code> and <code>bytesTotal</code> change when the nested loaders are recognized (this is normal). To control the default <code>auditSize</code> value, use the static <code>LoaderMax.defaultAuditSize</code> property.</li> | ||
| 110 | * <li><strong> maxConnections : uint</strong> - Maximum number of simultaneous connections that should be used while loading the LoaderMax queue. A higher number will generally result in faster overall load times for the group. The default is 2. This value is instance-based, not system-wide, so if you have two LoaderMax instances that both have a <code>maxConnections</code> value of 3 and they are both loading, there could be up to 6 connections at a time total. Sometimes there are limits imposed by the Flash Player itself or the browser or the user's system, but LoaderMax will do its best to honor the <code>maxConnections</code> you define.</li> | ||
| 111 | * <li><strong> skipFailed : Boolean</strong> - If <code>skipFailed</code> is <code>true</code> (the default), any failed loaders in the queue will be skipped. Otherwise, the LoaderMax will stop when it hits a failed loader and the LoaderMax's status will become <code>LoaderStatus.FAILED</code>.</li> | ||
| 112 | * <li><strong> skipPaused : Boolean</strong> - If <code>skipPaused</code> is <code>true</code> (the default), any paused loaders in the queue will be skipped. Otherwise, the LoaderMax will stop when it hits a paused loader and the LoaderMax's status will become <code>LoaderStatus.FAILED</code>.</li> | ||
| 113 | * <li><strong> loaders : Array</strong> - An array of loaders (ImageLoaders, SWFLoaders, XMLLoaders, MP3Loaders, other LoaderMax instances, etc.) that should be immediately inserted into the LoaderMax.</li> | ||
| 114 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want this LoaderMax to be required as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:LoaderMax = new LoaderMax({name:"mainQueue", requireWithRoot:this.root});</code></li> | ||
| 115 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 116 | * | ||
| 117 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 118 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 119 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 120 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 121 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either an error or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 122 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader or any of its children fails (typically because of an IO_ERROR or SECURITY_ERROR). Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 123 | * <li><strong> onChildOpen : Function</strong> - A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time one of the loader's children (or any descendant) begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 124 | * <li><strong> onChildProgress : Function</strong> - A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time one of the loader's children (or any descendant) dispatches a <code>PROGRESS</code> event. To listen for changes in the LoaderMax's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the LoaderMax, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 125 | * <li><strong> onChildComplete : Function</strong> - A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time one of the loader's children (or any descendant) finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 126 | * <li><strong> onChildCancel : Function</strong> - A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on one of the loader's children (or any descendant) due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 127 | * <li><strong> onChildFail : Function</strong> - A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time one of the loader's children (or any descendant) fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 128 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 129 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 130 | * <li><strong> onScriptAccessDenied : Function</strong> - A handler function for <code>LoaderEvent.SCRIPT_ACCESS_DENIED</code> events which are dispatched when one of the LoaderMax's children (or any descendant) is loaded from another domain and no crossdomain.xml is in place to grant full script access for things like smoothing or BitmapData manipulation. Make sure your function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 131 | * </ul><br /><br /> | ||
| 132 | * | ||
| 133 | * <strong>Note:</strong> Using a <code><a href="data/LoaderMaxVars.html">LoaderMaxVars</a></code> instance | ||
| 134 | * instead of a generic object to define your <code>vars</code> is a bit more verbose but provides | ||
| 135 | * code hinting and improved debugging because it enforces strict data typing. Use whichever one you prefer.<br /><br /> | ||
| 136 | * | ||
| 137 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 138 | * | ||
| 139 | * @see com.greensock.loading.data.LoaderMaxVars | ||
| 140 | * | ||
| 141 | * @author Jack Doyle, jack@greensock.com | ||
| 142 | */ | ||
| 143 | public class LoaderMax extends LoaderCore { | ||
| 144 | /** @private **/ | ||
| 145 | public static const version:Number = 1.46; | ||
| 146 | /** The default value that will be used for the <code>estimatedBytes</code> on loaders that don't declare one in the <code>vars</code> parameter of the constructor. **/ | ||
| 147 | public static var defaultEstimatedBytes:uint = 20000; | ||
| 148 | /** Controls the default value of <code>auditSize</code> in LoaderMax instances (normally <code>true</code>). For most situations, the auditSize feature is very convenient for ensuring that the overall progress of LoaderMax instances is reported accurately, but when working with very large quantities of files that have no <code>estimatedBytes</code> defined, some developers prefer to turn auditSize off by default. Of course you can always override the default for individual LoaderMax instances by defining an <code>auditSize</code> value in the <code>vars</code> parameter of the constructor. **/ | ||
| 149 | public static var defaultAuditSize:Boolean = true; | ||
| 150 | /** The class used by ImageLoaders, SWFLoaders, and VideoLoaders to create the containers into which they'll dump their rawContent - by default it is the <code>com.greensock.loading.display.ContentDisplay</code> class but if you're using Flex, it is typically best to change this to <code>com.greensock.loading.display.FlexContentDisplay</code>. You only need to do this once, like <br /><code>import com.greensock.loading.LoaderMax;<br />import com.greensock.loading.display.FlexContentDisplay;<br />LoaderMax.contentDisplayClass = FlexContentDisplay;</code> **/ | ||
| 151 | public static var contentDisplayClass:Class; | ||
| 152 | |||
| 153 | /** @private **/ | ||
| 154 | protected var _loaders:Array; | ||
| 155 | /** @private **/ | ||
| 156 | protected var _activeLoaders:Dictionary; | ||
| 157 | |||
| 158 | /** If <code>skipFailed</code> is <code>true</code> (the default), any failed loaders in the queue will be skipped. Otherwise, the LoaderMax will stop when it hits a failed loader and the LoaderMax's status will become <code>LoaderStatus.FAILED</code>. Skipped loaders are also ignored when the LoaderMax determines its <code>bytesLoaded, bytesTotal</code>, and <code>progress</code> values. **/ | ||
| 159 | public var skipFailed:Boolean; | ||
| 160 | /** If <code>skipPaused</code> is <code>true</code> (the default), any paused loaders in the queue will be skipped. Otherwise, the LoaderMax will stop when it hits a paused loader and the LoaderMax's status will become <code>LoaderStatus.FAILED</code>. Skipped loaders are also ignored when the LoaderMax determines its <code>bytesLoaded, bytesTotal</code>, and <code>progress</code> values. **/ | ||
| 161 | public var skipPaused:Boolean; | ||
| 162 | /** Maximum number of simultaneous connections that should be used while loading the LoaderMax queue. A higher number will generally result in faster overall load times for the group. The default is 2. This value is instance-based, not system-wide, so if you have two LoaderMax instances that both have a <code>maxConnections</code> value of 3 and they are both loading, there could be up to 6 connections at a time total. **/ | ||
| 163 | public var maxConnections:uint; | ||
| 164 | |||
| 165 | /** | ||
| 166 | * Constructor | ||
| 167 | * | ||
| 168 | * @param vars An object containing optional configuration details. For example: <code>new LoaderMax({name:"queue", onComplete:completeHandler, onProgress:progressHandler, maxConnections:3})</code>.<br /><br /> | ||
| 169 | * | ||
| 170 | * The following special properties can be passed into the LoaderMax constructor via the <code>vars</code> parameter | ||
| 171 | * which can be either a generic object or a <code><a href="data/LoaderMaxVars.html">LoaderMaxVars</a></code> object:<br /> | ||
| 172 | * <ul> | ||
| 173 | * <li><strong> name : String</strong> - A name that is used to identify the LoaderMax instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 174 | * <li><strong> auditSize : Boolean</strong> - By default, when the LoaderMax begins to load it quickly loops through its children and if it finds any that don't have an <code>estimatedBytes</code> defined, it will briefly open a URLStream in order to attempt to determine its <code>bytesTotal</code>, immediately closing the URLStream once the value has been determined. This causes a brief delay initially, but greatly improves the accuracy of the <code>progress</code> and <code>bytesTotal</code> values. Set <code>auditSize</code> to <code>false</code> to prevent the LoaderMax from auditing its childrens' size (it is <code>true</code> by default). For maximum performance, it is best to define an <code>estimatedBytes</code> value for as many loaders as possible to avoid the delay caused by audits. When the LoaderMax audits an XMLLoader, it cannot recognize loaders that will be created from the XML data nor can it recognize loaders inside subloaded swf files from a SWFLoader (it would take far too long to load sufficient data for that - audits should be as fast as possible). If you do not set an appropriate <code>estimatedSize</code> for XMLLoaders or SWFLoaders that contain LoaderMax loaders, you'll notice that the parent LoaderMax's <code>progress</code> and <code>bytesTotal</code> change when the nested loaders are recognized (this is normal). To control the default <code>auditSize</code> value, use the static <code>LoaderMax.defaultAuditSize</code> property.</li> | ||
| 175 | * <li><strong> maxConnections : uint</strong> - Maximum number of simultaneous connections that should be used while loading the LoaderMax queue. A higher number will generally result in faster overall load times for the group. The default is 2. This value is instance-based, not system-wide, so if you have two LoaderMax instances that both have a <code>maxConnections</code> value of 3 and they are both loading, there could be up to 6 connections at a time total. Sometimes there are limits imposed by the Flash Player itself or the browser or the user's system, but LoaderMax will do its best to honor the <code>maxConnections</code> you define.</li> | ||
| 176 | * <li><strong> skipFailed : Boolean</strong> - If <code>skipFailed</code> is <code>true</code> (the default), any failed loaders in the queue will be skipped. Otherwise, the LoaderMax will stop when it hits a failed loader and the LoaderMax's status will become <code>LoaderStatus.FAILED</code>.</li> | ||
| 177 | * <li><strong> skipPaused : Boolean</strong> - If <code>skipPaused</code> is <code>true</code> (the default), any paused loaders in the queue will be skipped. Otherwise, the LoaderMax will stop when it hits a paused loader and the LoaderMax's status will become <code>LoaderStatus.FAILED</code>.</li> | ||
| 178 | * <li><strong> loaders : Array</strong> - An array of loaders (ImageLoaders, SWFLoaders, XMLLoaders, MP3Loaders, other LoaderMax instances, etc.) that should be immediately inserted into the LoaderMax.</li> | ||
| 179 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want this LoaderMax to be required as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:LoaderMax = new LoaderMax({name:"mainQueue", requireWithRoot:this.root});</code></li> | ||
| 180 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 181 | * | ||
| 182 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 183 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 184 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 185 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 186 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either an error or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 187 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader or any of its children fails (typically because of an IO_ERROR or SECURITY_ERROR). Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 188 | * <li><strong> onChildOpen : Function</strong> - A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time one of the loader's children (or any descendant) begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 189 | * <li><strong> onChildProgress : Function</strong> - A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time one of the loader's children (or any descendant) dispatches a <code>PROGRESS</code> event. To listen for changes in the LoaderMax's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the LoaderMax, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 190 | * <li><strong> onChildComplete : Function</strong> - A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time one of the loader's children (or any descendant) finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 191 | * <li><strong> onChildCancel : Function</strong> - A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on one of the loader's children (or any descendant) due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 192 | * <li><strong> onChildFail : Function</strong> - A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time one of the loader's children (or any descendant) fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 193 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 194 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 195 | * <li><strong> onScriptAccessDenied : Function</strong> - A handler function for <code>LoaderEvent.SCRIPT_ACCESS_DENIED</code> events which are dispatched when one of the LoaderMax's children (or any descendant) is loaded from another domain and no crossdomain.xml is in place to grant full script access for things like smoothing or BitmapData manipulation. Make sure your function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 196 | * </ul> | ||
| 197 | * @see com.greensock.loading.data.LoaderMaxVars | ||
| 198 | */ | ||
| 199 | public function LoaderMax(vars:Object=null) { | ||
| 200 | super(vars); | ||
| 201 | _type = "LoaderMax"; | ||
| 202 | _loaders = []; | ||
| 203 | _activeLoaders = new Dictionary(); | ||
| 204 | this.skipFailed = Boolean(this.vars.skipFailed != false); | ||
| 205 | this.skipPaused = Boolean(this.vars.skipPaused != false); | ||
| 206 | this.maxConnections = ("maxConnections" in this.vars) ? uint(this.vars.maxConnections) : 2; | ||
| 207 | if (this.vars.loaders is Array) { | ||
| 208 | for (var i:int = 0; i < this.vars.loaders.length; i++) { | ||
| 209 | insert(this.vars.loaders[i], i); | ||
| 210 | } | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | /** | ||
| 215 | * Analyzes a url or array of urls and attempts to automatically create the appropriate loader(s) based | ||
| 216 | * on file extension(s) in the url(s), returning either an individual loader like an ImageLoader, | ||
| 217 | * SWFLoader, XMLLoader, etc or if an array is passed in, a LoaderMax will be returned containing | ||
| 218 | * a child for each parsed url in the array. Arrays may also contain loader instances (not just url Strings). | ||
| 219 | * For example:<br /> | ||
| 220 | * @example Single loader example:<listing version="3.0"> | ||
| 221 | import com.greensock.loading.~~; | ||
| 222 | import com.greensock.loading.core.~~; | ||
| 223 | import com.greensock.events.LoaderEvent; | ||
| 224 | |||
| 225 | //activate the necessary loaders so that their file extensions can be recognized (do this once) | ||
| 226 | LoaderMax.activate([ImageLoader, SWFLoader, XMLLoader]); | ||
| 227 | |||
| 228 | //now parse a url and create the correct type of loader (an ImageLoader in this case because the file extension is ".jpg") | ||
| 229 | var loader:LoaderCore = LoaderMax.parse("../img/photo1.jpg", {name:"parsedLoader", onComplete:completeHandler}); | ||
| 230 | |||
| 231 | //begin loading | ||
| 232 | loader.load(); | ||
| 233 | |||
| 234 | function completeHandler(event:LoaderEvent):void { | ||
| 235 | trace("finished loading " + event.target); | ||
| 236 | } | ||
| 237 | </listing> | ||
| 238 | * If an array is passed to the <code>LoaderMax.parse()</code> method, it will create a LoaderMax instance | ||
| 239 | * and add the necessary children based on the contents of the array:<br /> | ||
| 240 | * @example Array example:<listing version="3.0"> | ||
| 241 | import com.greensock.loading.~~; | ||
| 242 | import com.greensock.loading.core.~~; | ||
| 243 | import com.greensock.events.LoaderEvent; | ||
| 244 | |||
| 245 | //activate the necessary loaders so that their file extensions can be recognized (do this once) | ||
| 246 | LoaderMax.activate([ImageLoader, SWFLoader, XMLLoader, MP3Loader]); | ||
| 247 | |||
| 248 | var urls:Array = ["img/photo1.jpg","../../xml/data.xml","swf/main.swf","http://www.greensock.com/audio/music.mp3"]; | ||
| 249 | |||
| 250 | //now parse all of the urls, creating a LoaderMax that contains the correct type of loaders (an ImageLoader, XMLLoader, SWFLoader, and MP3Loader respectively) | ||
| 251 | var loader:LoaderMax = LoaderMax.parse(urls, {name:"mainQueue", onComplete:completeHandler}) as LoaderMax; | ||
| 252 | |||
| 253 | //begin loading | ||
| 254 | loader.load(); | ||
| 255 | |||
| 256 | function completeHandler(event:LoaderEvent):void { | ||
| 257 | trace("finished loading " + loader.numChildren + " loaders."); | ||
| 258 | } | ||
| 259 | </listing> | ||
| 260 | * | ||
| 261 | * @param data A String or an array of Strings (and/or loader instances) to parse. | ||
| 262 | * @param vars The <code>vars</code> object to pass the loader's constructor. If <code>data</code> is an array, this <code>vars</code> will be passed to the LoaderMax instance that gets created, and no <code>vars</code> object will be passed to the child loaders that get created. | ||
| 263 | * @return If <code>data</code> is an array, <code>parse()</code> will return a LoaderMax. Otherwise, it will return the appropriate loader based on the file extension found in the URL. In any case, the object returned will be a <code>LoaderCore</code> object (all LoaderMax loaders extend LoaderCore, so if you need to datatype your object use <code>com.greensock.loading.core.LoaderCore</code>). The return value is typed as "*" in order to avoid compiler errors when developers forget to cast ther objects like <code>var image:ImageLoader = LoaderMax.parse("photo.jpg") as ImageLoader</code> | ||
| 264 | */ | ||
| 265 | public static function parse(data:*, vars:Object=null):* { | ||
| 266 | if (data is Array) { | ||
| 267 | var queue:LoaderMax = new LoaderMax(vars); | ||
| 268 | var l:int = data.length; | ||
| 269 | for (var i:int = 0; i < l; i++) { | ||
| 270 | queue.append(LoaderMax.parse(data[i])); | ||
| 271 | } | ||
| 272 | return queue; | ||
| 273 | } else if (data is String) { | ||
| 274 | var s:String = data.toLowerCase().split("?")[0]; | ||
| 275 | s = s.substr(s.lastIndexOf(".") + 1); | ||
| 276 | if (s in _extensions) { | ||
| 277 | return new _extensions[s](data, vars); | ||
| 278 | } | ||
| 279 | } else if (data is LoaderCore) { | ||
| 280 | return data as LoaderCore; | ||
| 281 | } | ||
| 282 | throw new Error("LoaderMax could not parse " + data + ". Don't forget to use LoaderMax.activate() to activate the necessary types of loaders."); | ||
| 283 | return null; | ||
| 284 | } | ||
| 285 | |||
| 286 | /** @private **/ | ||
| 287 | override protected function _load():void { | ||
| 288 | _loadNext(null); | ||
| 289 | } | ||
| 290 | |||
| 291 | /** | ||
| 292 | * Appends a loader to the end of the queue. | ||
| 293 | * | ||
| 294 | * @param loader The loader to append to the queue. It can be any loader (ImageLoader, XMLLoader, SWFLoader, MP3Loader, another LoaderMax, etc.). | ||
| 295 | * @return The loader that was appended. | ||
| 296 | * @see #prepend() | ||
| 297 | * @see #insert() | ||
| 298 | * @see #remove() | ||
| 299 | */ | ||
| 300 | public function append(loader:LoaderCore):LoaderCore { | ||
| 301 | return insert(loader, _loaders.length); | ||
| 302 | } | ||
| 303 | |||
| 304 | /** | ||
| 305 | * Prepends a loader at the beginning of the queue (<code>append()</code> adds the loader to the end whereas <code>prepend()</code> adds it to the beginning). | ||
| 306 | * | ||
| 307 | * @param loader The loader to prepend to the queue. It can be any loader (ImageLoader, XMLLoader, SWFLoader, MP3Loader, another LoaderMax, etc.). | ||
| 308 | * @return The loader that was prepended. | ||
| 309 | * @see #append() | ||
| 310 | * @see #insert() | ||
| 311 | * @see #remove() | ||
| 312 | */ | ||
| 313 | public function prepend(loader:LoaderCore):LoaderCore { | ||
| 314 | return insert(loader, 0); | ||
| 315 | } | ||
| 316 | |||
| 317 | /** | ||
| 318 | * Inserts a loader at a particular position in the queue. Index values are zero-based just like arrays. | ||
| 319 | * For example, if the LoaderMax has 10 loaders in it already and you want to insert a loader at the 3rd | ||
| 320 | * position (index: 2) while moving the others back in the queue (like the way <code>splice()</code> works | ||
| 321 | * in arrays), you'd do:<br /><br /><code> | ||
| 322 | * | ||
| 323 | * queue.insert( new ImageLoader("img/photo.jpg"), 2);</code><br /><br /> | ||
| 324 | * | ||
| 325 | * When a new loader is added to the LoaderMax, the LoaderMax's status changes to <code>LoaderStatus.READY</code> | ||
| 326 | * unless it is paused or disposed. If the loader is already in the queue, it will be removed first. | ||
| 327 | * | ||
| 328 | * @param loader The loader to insert into the queue. It can be any loader (ImageLoader, XMLLoader, SWFLoader, MP3Loader, DataLoader, CSSLoader, another LoaderMax, etc.). | ||
| 329 | * @param index The index position at which the loader should be inserted, exactly like the way <code>splice()</code> works for arrays. Index values are 0-based, so the first position is 0, the second is 1, the third is 2, etc. | ||
| 330 | * @return The loader that was inserted | ||
| 331 | * @see #append() | ||
| 332 | * @see #prepend() | ||
| 333 | * @see #remove() | ||
| 334 | */ | ||
| 335 | public function insert(loader:LoaderCore, index:uint=999999999):LoaderCore { | ||
| 336 | if (loader == null || loader == this || _status == LoaderStatus.DISPOSED) { | ||
| 337 | return null; | ||
| 338 | } | ||
| 339 | if (this != loader.rootLoader) { | ||
| 340 | _removeLoader(loader, false); //in case it was already added. | ||
| 341 | } | ||
| 342 | loader.rootLoader.remove(loader); | ||
| 343 | |||
| 344 | if (index > _loaders.length) { | ||
| 345 | index = _loaders.length; | ||
| 346 | } | ||
| 347 | |||
| 348 | _loaders.splice(index, 0, loader); | ||
| 349 | if (this != _globalRootLoader) { | ||
| 350 | loader.addEventListener(LoaderEvent.PROGRESS, _progressHandler, false, 0, true); | ||
| 351 | loader.addEventListener("prioritize", _prioritizeHandler, false, 0, true); | ||
| 352 | for (var p:String in _listenerTypes) { | ||
| 353 | if (p != "onProgress" && p != "onInit") { | ||
| 354 | loader.addEventListener(_listenerTypes[p], _passThroughEvent, false, 0, true); | ||
| 355 | } | ||
| 356 | } | ||
| 357 | } | ||
| 358 | loader.addEventListener("dispose", _disposeHandler, false, 0, true); | ||
| 359 | _cacheIsDirty = true; | ||
| 360 | if (_status == LoaderStatus.LOADING) { | ||
| 361 | //do nothing | ||
| 362 | } else if (_status != LoaderStatus.PAUSED) { | ||
| 363 | _status = LoaderStatus.READY; | ||
| 364 | } else if (_prePauseStatus == LoaderStatus.COMPLETED) { | ||
| 365 | _prePauseStatus = LoaderStatus.READY; | ||
| 366 | } | ||
| 367 | return loader; | ||
| 368 | } | ||
| 369 | |||
| 370 | /** | ||
| 371 | * Removes a loader from the LoaderMax. | ||
| 372 | * | ||
| 373 | * @param loader The loader to remove from the LoaderMax | ||
| 374 | * @see #append() | ||
| 375 | * @see #insert() | ||
| 376 | * @see #prepend() | ||
| 377 | */ | ||
| 378 | public function remove(loader:LoaderCore):void { | ||
| 379 | _removeLoader(loader, true); | ||
| 380 | } | ||
| 381 | |||
| 382 | /** @private **/ | ||
| 383 | protected function _removeLoader(loader:LoaderCore, rootLoaderAppend:Boolean):void { | ||
| 384 | if (loader == null) { | ||
| 385 | return; | ||
| 386 | } | ||
| 387 | if (rootLoaderAppend && this != loader.rootLoader) { | ||
| 388 | loader.rootLoader.append(loader); | ||
| 389 | } | ||
| 390 | _removeLoaderListeners(loader, true); | ||
| 391 | _loaders.splice(getChildIndex(loader), 1); | ||
| 392 | if (loader in _activeLoaders) { | ||
| 393 | delete _activeLoaders[loader]; | ||
| 394 | loader.cancel(); | ||
| 395 | if (_status == LoaderStatus.LOADING) { | ||
| 396 | _loadNext(null); | ||
| 397 | } | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | /** | ||
| 402 | * Empties the LoaderMax of all its loaders and optionally disposes/unloads them. | ||
| 403 | * | ||
| 404 | * @param disposeChildren If <code>true</code> (the default), <code>dispose()</code> will be called on all loaders in the LoaderMax. | ||
| 405 | * @param unloadAllContent If <code>true</code>, the <code>content</code> of all child loaders will be unloaded. | ||
| 406 | * @see #dispose() | ||
| 407 | * @see #unload() | ||
| 408 | */ | ||
| 409 | public function empty(disposeChildren:Boolean=true, unloadAllContent:Boolean=false):void { | ||
| 410 | var i:int = _loaders.length; | ||
| 411 | while (--i > -1) { | ||
| 412 | if (disposeChildren) { | ||
| 413 | LoaderCore(_loaders[i]).dispose(unloadAllContent); | ||
| 414 | } else if (unloadAllContent) { | ||
| 415 | LoaderCore(_loaders[i]).unload(); | ||
| 416 | } else { | ||
| 417 | _removeLoader(_loaders[i], true); | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 423 | override protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 424 | if (newStatus == LoaderStatus.DISPOSED) { | ||
| 425 | _status = LoaderStatus.DISPOSED; //must set it first so that when events from children are dispatched, it doesn't trigger other unnecessary actions. | ||
| 426 | empty(true, Boolean(scrubLevel == 3)); | ||
| 427 | if (this.vars.requireWithRoot is DisplayObject) { | ||
| 428 | delete _rootLookup[this.vars.requireWithRoot]; | ||
| 429 | } | ||
| 430 | _activeLoaders = null; | ||
| 431 | } | ||
| 432 | if (scrubLevel <= 1) { | ||
| 433 | _cancelActiveLoaders(); | ||
| 434 | } | ||
| 435 | if (scrubLevel == 1) { | ||
| 436 | var i:int = _loaders.length; | ||
| 437 | while (--i > -1) { | ||
| 438 | LoaderCore(_loaders[i]).unload(); | ||
| 439 | } | ||
| 440 | } | ||
| 441 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 442 | _cacheIsDirty = true; | ||
| 443 | } | ||
| 444 | |||
| 445 | /** @private **/ | ||
| 446 | override protected function _calculateProgress():void { | ||
| 447 | _cachedBytesLoaded = 0; | ||
| 448 | _cachedBytesTotal = 0; | ||
| 449 | var i:int = _loaders.length; | ||
| 450 | var loader:LoaderCore, s:int; | ||
| 451 | while (--i > -1) { | ||
| 452 | loader = _loaders[i]; | ||
| 453 | s = loader.status; | ||
| 454 | if (s <= LoaderStatus.COMPLETED || (!this.skipPaused && s == LoaderStatus.PAUSED) || (!this.skipFailed && s == LoaderStatus.FAILED)) { | ||
| 455 | _cachedBytesLoaded += loader.bytesLoaded; | ||
| 456 | _cachedBytesTotal += loader.bytesTotal; | ||
| 457 | } | ||
| 458 | } | ||
| 459 | _cacheIsDirty = false; | ||
| 460 | } | ||
| 461 | |||
| 462 | /** @private **/ | ||
| 463 | protected function _cancelActiveLoaders():void { | ||
| 464 | var i:int = _loaders.length; | ||
| 465 | var loader:LoaderCore; | ||
| 466 | while (--i > -1) { | ||
| 467 | loader = _loaders[i]; | ||
| 468 | if (loader.status == LoaderStatus.LOADING) { | ||
| 469 | delete _activeLoaders[loader]; | ||
| 470 | _removeLoaderListeners(loader, false); | ||
| 471 | loader.cancel(); | ||
| 472 | } | ||
| 473 | } | ||
| 474 | } | ||
| 475 | |||
| 476 | /** @private **/ | ||
| 477 | protected function _removeLoaderListeners(loader:LoaderCore, all:Boolean):void { | ||
| 478 | loader.removeEventListener(LoaderEvent.COMPLETE, _loadNext); | ||
| 479 | loader.removeEventListener(LoaderEvent.CANCEL, _loadNext); | ||
| 480 | if (all) { | ||
| 481 | loader.removeEventListener(LoaderEvent.PROGRESS, _progressHandler); | ||
| 482 | loader.removeEventListener("prioritize", _prioritizeHandler); | ||
| 483 | loader.removeEventListener("dispose", _disposeHandler); | ||
| 484 | for (var p:String in _listenerTypes) { | ||
| 485 | if (p != "onProgress" && p != "onInit") { | ||
| 486 | loader.removeEventListener(_listenerTypes[p], _passThroughEvent); | ||
| 487 | } | ||
| 488 | } | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | /** | ||
| 493 | * Returns and array of child loaders that currently have a particular <code>status</code>. For example, | ||
| 494 | * to find all loaders inside the LoaderMax instance that are actively in the process of loading: <br /><br /><code> | ||
| 495 | * | ||
| 496 | * loader.getChildrenByStatus(LoaderStatus.LOADING, false); </code> | ||
| 497 | * | ||
| 498 | * @param status Status code like <code>LoaderStatus.READY, LoaderStatus.LOADING, LoaderStatus.COMPLETE, LoaderStatus.PAUSED,</code> or <code>LoaderStatus.FAILED</code>. | ||
| 499 | * @param includeNested If <code>true</code>, loaders that are nested inside other loaders (like LoaderMax instances or XMLLoaders or SWFLoaders) will be returned in the array. | ||
| 500 | * @return An array of loaders that match the defined <code>status</code>. | ||
| 501 | * @see #getChildren() | ||
| 502 | * @see #getLoader() | ||
| 503 | * @see #numChildren | ||
| 504 | */ | ||
| 505 | public function getChildrenByStatus(status:int, includeNested:Boolean=false):Array { | ||
| 506 | var a:Array = []; | ||
| 507 | var loaders:Array = getChildren(includeNested, false); | ||
| 508 | var l:int = loaders.length; | ||
| 509 | for (var i:int = 0; i < l; i++) { | ||
| 510 | if (LoaderCore(loaders[i]).status == status) { | ||
| 511 | a.push(loaders[i]); | ||
| 512 | } | ||
| 513 | } | ||
| 514 | return a; | ||
| 515 | } | ||
| 516 | |||
| 517 | /** | ||
| 518 | * Returns and array of all child loaders inside the LoaderMax, optionally exposing more deeply nested | ||
| 519 | * instances as well (like loaders inside a child LoaderMax instance). | ||
| 520 | * | ||
| 521 | * @param includeNested If <code>true</code>, loaders that are nested inside child LoaderMax, XMLLoader, or SWFLoader instances will be included in the returned array as well. The default is <code>false</code>. | ||
| 522 | * @param omitLoaderMaxes If <code>true</code>, no LoaderMax instances will be returned in the array; only LoaderItems like ImageLoaders, XMLLoaders, SWFLoaders, MP3Loaders, etc. The default is <code>false</code>. | ||
| 523 | * @return An array of loaders. | ||
| 524 | * @see #getChildrenByStatus() | ||
| 525 | * @see #getLoader() | ||
| 526 | * @see #numChildren | ||
| 527 | */ | ||
| 528 | public function getChildren(includeNested:Boolean=false, omitLoaderMaxes:Boolean=false):Array { | ||
| 529 | var a:Array = []; | ||
| 530 | var l:int = _loaders.length; | ||
| 531 | for (var i:int = 0; i < l; i++) { | ||
| 532 | if (!omitLoaderMaxes || !(_loaders[i] is LoaderMax)) { | ||
| 533 | a.push(_loaders[i]); | ||
| 534 | } | ||
| 535 | if (includeNested && _loaders[i].hasOwnProperty("getChildren")) { | ||
| 536 | a = a.concat(_loaders[i].getChildren(true, omitLoaderMaxes)); | ||
| 537 | } | ||
| 538 | } | ||
| 539 | return a; | ||
| 540 | } | ||
| 541 | |||
| 542 | /** | ||
| 543 | * Immediately prepends a value to the beginning of each child loader's <code>url</code>. For example, | ||
| 544 | * if the "myLoaderMax" instance contains 3 ImageLoaders with the urls "image1.jpg", "image2.jpg", and "image3.jpg" | ||
| 545 | * and you'd like to add "http://www.greensock.com/images/" to the beginning of them all, you'd do:<br /><br /><code> | ||
| 546 | * | ||
| 547 | * myLoaderMax.prependURLs("http://www.greensock.com/images/", false);<br /><br /></code> | ||
| 548 | * | ||
| 549 | * Now the ImageLoader urls would be "http://www.greensock.com/images/image1.jpg", "http://www.greensock.com/images/image2.jpg", | ||
| 550 | * and "http://www.greensock.com/images/image3.jpg" respectively. <br /><br /> | ||
| 551 | * | ||
| 552 | * <code>prependURLs()</code> permanently affects each child loader's url meaning that | ||
| 553 | * <code>LoaderMax.getContent("image1.jpg")</code> would not find the loader whose <code>url</code> | ||
| 554 | * is now "http://www.greensock.com/images/image1.jpg" (although you could simply use its <code>name</code> | ||
| 555 | * instead of its <code>url</code> to find it). It also means that if a single loader has been | ||
| 556 | * inserted into multiple LoaderMax instances, its <code>url</code> change affects them all. <br /><br /> | ||
| 557 | * | ||
| 558 | * <code>prependURLs()</code> only affects loaders that are children of the LoaderMax when | ||
| 559 | * the method is called - it does <strong>not</strong> affect loaders that are inserted later. <br /><br /> | ||
| 560 | * | ||
| 561 | * <code>prependURLs()</code> does <strong>NOT</strong> affect any <code>alternateURL</code> values that are defined | ||
| 562 | * for each child loader. | ||
| 563 | * | ||
| 564 | * @param value The String that should be prepended to each child loader | ||
| 565 | * @param includeNested If <code>true</code>, loaders nested inside child LoaderMax instances will also be affected. It is <code>false</code> by default. | ||
| 566 | * @see #replaceURLText() | ||
| 567 | */ | ||
| 568 | public function prependURLs(prependText:String, includeNested:Boolean=false):void { | ||
| 569 | var loaders:Array = getChildren(includeNested, true); | ||
| 570 | var i:int = loaders.length; | ||
| 571 | while (--i > -1) { | ||
| 572 | LoaderItem(loaders[i]).url = prependText + LoaderItem(loaders[i]).url; | ||
| 573 | } | ||
| 574 | } | ||
| 575 | |||
| 576 | /** | ||
| 577 | * Immediately replaces a certain substring in each child loader's <code>url</code> with another string, | ||
| 578 | * making it simple to do something like change <code>"{imageDirectory}image1.jpg"</code> to | ||
| 579 | * <code>"http://www.greensock.com/images/image1.jpg"</code>. For example, | ||
| 580 | * if the "myLoaderMax" instance contains 3 ImageLoaders with the urls <code>"{imageDirectory}image1.jpg", | ||
| 581 | * "{imageDirectory}image2.jpg",</code> and <code>"{imageDirectory}image3.jpg"</code> | ||
| 582 | * and you'd like to replace <code>{imageDirectory}</code> with <code>http://www.greensock.com/images/</code> | ||
| 583 | * you'd do:<br /><br /><code> | ||
| 584 | * | ||
| 585 | * myLoaderMax.replaceURLText("{imageDirectory}", "http://www.greensock.com/images/", false);<br /><br /></code> | ||
| 586 | * | ||
| 587 | * Now the ImageLoader urls would be "http://www.greensock.com/images/image1.jpg", "http://www.greensock.com/images/image2.jpg", | ||
| 588 | * and "http://www.greensock.com/images/image3.jpg" respectively. <br /><br /> | ||
| 589 | * | ||
| 590 | * <code>replaceURLText()</code> permanently affects each child loader's <code>url</code> meaning that | ||
| 591 | * <code>LoaderMax.getContent("image1.jpg")</code> would not find the loader whose <code>url</code> | ||
| 592 | * is now "http://www.greensock.com/images/image1.jpg" (although you could simply use its <code>name</code> | ||
| 593 | * instead of its <code>url</code> to find it). It also means that if a single loader has been | ||
| 594 | * inserted into multiple LoaderMax instances, its <code>url</code> change affects them all. <br /><br /> | ||
| 595 | * | ||
| 596 | * <code>replaceURLText()</code> only affects loaders that are children of the LoaderMax when | ||
| 597 | * the method is called - it does <strong>not</strong> affect loaders that are inserted later. <br /><br /> | ||
| 598 | * | ||
| 599 | * <code>replaceURLText()</code> <strong>does</strong> affect <code>alternateURL</code> values for child loaders. | ||
| 600 | * | ||
| 601 | * @param fromText The old String that should be replaced in each child loader. | ||
| 602 | * @param toText The new String that should replace the <code>fromText</code>. | ||
| 603 | * @param includeNested If <code>true</code>, loaders nested inside child LoaderMax instances will also be affected. It is <code>false</code> by default. | ||
| 604 | * @see #prependURLs() | ||
| 605 | */ | ||
| 606 | public function replaceURLText(fromText:String, toText:String, includeNested:Boolean=false):void { | ||
| 607 | var loaders:Array = getChildren(includeNested, true); | ||
| 608 | var loader:LoaderItem; | ||
| 609 | var i:int = loaders.length; | ||
| 610 | while (--i > -1) { | ||
| 611 | loader = loaders[i]; | ||
| 612 | loader.url = loader.url.split(fromText).join(toText); | ||
| 613 | if ("alternateURL" in loader.vars) { | ||
| 614 | loader.vars.alternateURL = loader.vars.alternateURL.split(fromText).join(toText); | ||
| 615 | } | ||
| 616 | } | ||
| 617 | } | ||
| 618 | |||
| 619 | /** | ||
| 620 | * Finds a loader inside the LoaderMax based on its name or url. For example:<br /><br /><code> | ||
| 621 | * | ||
| 622 | * var loader:ImageLoader = queue.getLoader("myPhoto1") as ImageLoader;<br /><br /></code> | ||
| 623 | * | ||
| 624 | * @param nameOrURL The name or url associated with the loader that should be found. | ||
| 625 | * @return The loader associated with the name or url. | ||
| 626 | * @see #getContent() | ||
| 627 | * @see #getChildren() | ||
| 628 | * @see #getChildrenByStatus() | ||
| 629 | */ | ||
| 630 | public function getLoader(nameOrURL:String):* { | ||
| 631 | var i:int = _loaders.length; | ||
| 632 | var loader:LoaderCore; | ||
| 633 | while (--i > -1) { | ||
| 634 | loader = _loaders[i]; | ||
| 635 | if (loader.name == nameOrURL || (loader is LoaderItem && (loader as LoaderItem).url == nameOrURL)) { | ||
| 636 | return loader; | ||
| 637 | } else if (loader.hasOwnProperty("getLoader")) { | ||
| 638 | loader = (loader as Object).getLoader(nameOrURL) as LoaderCore; | ||
| 639 | if (loader != null) { | ||
| 640 | return loader; | ||
| 641 | } | ||
| 642 | } | ||
| 643 | } | ||
| 644 | return null; | ||
| 645 | } | ||
| 646 | |||
| 647 | /** | ||
| 648 | * Finds the content of a loader inside the LoaderMax based on its name or url. For example:<br /><br /><code> | ||
| 649 | * | ||
| 650 | * var image:Bitmap = queue.getContent("myPhoto1");<br /><br /></code> | ||
| 651 | * | ||
| 652 | * @param nameOrURL The name or url associated with the loader whose content should be found. | ||
| 653 | * @return The content that was loaded by the loader which varies by the type of loader: | ||
| 654 | * <ul> | ||
| 655 | * <li><strong> ImageLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the ImageLoader's <code>rawContent</code> (a <code>flash.display.Bitmap</code> unless script access was denied in which case <code>rawContent</code> will be a <code>flash.display.Loader</code> to avoid security errors). For Flex users, you can set <code>LoaderMax.defaultContentDisplay</code> to <code>FlexContentDisplay</code> in which case ImageLoaders, SWFLoaders, and VideoLoaders will return a <code>com.greensock.loading.display.FlexContentDisplay</code> instance instead.</li> | ||
| 656 | * <li><strong> SWFLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the SWFLoader's <code>rawContent</code> (the swf's <code>root</code> DisplayObject unless script access was denied in which case <code>rawContent</code> will be a <code>flash.display.Loader</code> to avoid security errors). For Flex users, you can set <code>LoaderMax.defaultContentDisplay</code> to <code>FlexContentDisplay</code> in which case ImageLoaders, SWFLoaders, and VideoLoaders will return a <code>com.greensock.loading.display.FlexContentDisplay</code> instance instead.</li> | ||
| 657 | * <li><strong> VideoLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the VideoLoader's <code>rawContent</code> (a Video object to which the NetStream was attached). For Flex users, you can set <code>LoaderMax.defaultContentDisplay</code> to <code>FlexContentDisplay</code> in which case ImageLoaders, SWFLoaders, and VideoLoaders will return a <code>com.greensock.loading.display.FlexContentDisplay</code> instance instead.</li> | ||
| 658 | * <li><strong> XMLLoader </strong> - XML</li> | ||
| 659 | * <li><strong> DataLoader </strong> | ||
| 660 | * <ul> | ||
| 661 | * <li><code>String</code> if the DataLoader's <code>format</code> vars property is <code>"text"</code> (the default).</li> | ||
| 662 | * <li><code>flash.utils.ByteArray</code> if the DataLoader's <code>format</code> vars property is <code>"binary"</code>.</li> | ||
| 663 | * <li><code>flash.net.URLVariables</code> if the DataLoader's <code>format</code> vars property is <code>"variables"</code>.</li> | ||
| 664 | * </ul></li> | ||
| 665 | * <li><strong> CSSLoader </strong> - <code>flash.text.StyleSheet</code></li> | ||
| 666 | * <li><strong> MP3Loader </strong> - <code>flash.media.Sound</code></li> | ||
| 667 | * <li><strong> LoaderMax </strong> - an array containing the content objects from each of its child loaders.</li> | ||
| 668 | * </ul> | ||
| 669 | * @see #getLoader() | ||
| 670 | * @see #content | ||
| 671 | */ | ||
| 672 | public function getContent(nameOrURL:String):* { | ||
| 673 | var loader:LoaderCore = this.getLoader(nameOrURL); | ||
| 674 | return (loader != null) ? loader.content : null; | ||
| 675 | } | ||
| 676 | |||
| 677 | /** | ||
| 678 | * Finds the index position of a particular loader in the LoaderMax. Index values are always zero-based, | ||
| 679 | * meaning the first position is 0, the second is 1, the third is 2, etc. | ||
| 680 | * | ||
| 681 | * @param loader The loader whose index position should be returned | ||
| 682 | * @return The index position of the loader | ||
| 683 | * @see #getChildren() | ||
| 684 | * @see #getChildrenByStatus() | ||
| 685 | */ | ||
| 686 | public function getChildIndex(loader:LoaderCore):uint { | ||
| 687 | var i:int = _loaders.length; | ||
| 688 | while (--i > -1) { | ||
| 689 | if (_loaders[i] == loader) { | ||
| 690 | return i; | ||
| 691 | } | ||
| 692 | } | ||
| 693 | return 999999999; | ||
| 694 | } | ||
| 695 | |||
| 696 | /** @inheritDoc **/ | ||
| 697 | override public function auditSize():void { | ||
| 698 | if (!this.auditedSize) { | ||
| 699 | _auditSize(null); | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 703 | /** @private **/ | ||
| 704 | protected function _auditSize(event:Event=null):void { | ||
| 705 | if (event != null) { | ||
| 706 | event.target.removeEventListener("auditedSize", _auditSize); | ||
| 707 | } | ||
| 708 | var l:uint = _loaders.length; | ||
| 709 | var maxStatus:int = (this.skipPaused) ? LoaderStatus.COMPLETED : LoaderStatus.PAUSED; | ||
| 710 | var loader:LoaderCore, found:Boolean; | ||
| 711 | for (var i:int = 0; i < l; i++) { | ||
| 712 | loader = _loaders[i]; | ||
| 713 | if (!loader.auditedSize && loader.status <= maxStatus) { | ||
| 714 | if (!found) { | ||
| 715 | loader.addEventListener("auditedSize", _auditSize, false, 0, true); | ||
| 716 | } | ||
| 717 | found = true; | ||
| 718 | loader.auditSize(); | ||
| 719 | } | ||
| 720 | } | ||
| 721 | if (!found) { | ||
| 722 | if (_status == LoaderStatus.LOADING) { | ||
| 723 | _loadNext(null); | ||
| 724 | } | ||
| 725 | dispatchEvent(new Event("auditedSize")); | ||
| 726 | } | ||
| 727 | } | ||
| 728 | |||
| 729 | |||
| 730 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 731 | |||
| 732 | /** @private **/ | ||
| 733 | protected function _loadNext(event:Event=null):void { | ||
| 734 | if (event != null) { | ||
| 735 | delete _activeLoaders[event.target]; | ||
| 736 | _removeLoaderListeners(LoaderCore(event.target), false); | ||
| 737 | } | ||
| 738 | if (_status == LoaderStatus.LOADING) { | ||
| 739 | |||
| 740 | var audit:Boolean = ("auditSize" in this.vars) ? Boolean(this.vars.auditSize) : LoaderMax.defaultAuditSize; | ||
| 741 | if (audit && !this.auditedSize) { | ||
| 742 | _auditSize(null); | ||
| 743 | return; | ||
| 744 | } | ||
| 745 | |||
| 746 | var loader:LoaderCore; | ||
| 747 | var l:uint = _loaders.length; | ||
| 748 | var activeCount:uint = 0; | ||
| 749 | _calculateProgress(); | ||
| 750 | for (var i:int = 0; i < l; i++) { | ||
| 751 | loader = _loaders[i]; | ||
| 752 | if (!this.skipPaused && loader.status == LoaderStatus.PAUSED) { | ||
| 753 | super._failHandler(new LoaderEvent(LoaderEvent.FAIL, this, "Did not complete LoaderMax because skipPaused was false and " + loader.toString() + " was paused.")); | ||
| 754 | return; | ||
| 755 | |||
| 756 | } else if (!this.skipFailed && loader.status == LoaderStatus.FAILED) { | ||
| 757 | super._failHandler(new LoaderEvent(LoaderEvent.FAIL, this, "Did not complete LoaderMax because skipFailed was false and " + loader.toString() + " failed.")); | ||
| 758 | return; | ||
| 759 | |||
| 760 | } else if (loader.status <= LoaderStatus.LOADING) { | ||
| 761 | activeCount++; | ||
| 762 | if (!(loader in _activeLoaders)) { | ||
| 763 | _activeLoaders[loader] = true; | ||
| 764 | loader.addEventListener(LoaderEvent.COMPLETE, _loadNext); | ||
| 765 | loader.addEventListener(LoaderEvent.CANCEL, _loadNext); | ||
| 766 | loader.load(false); | ||
| 767 | } | ||
| 768 | if (activeCount == this.maxConnections) { | ||
| 769 | break; | ||
| 770 | } | ||
| 771 | } | ||
| 772 | } | ||
| 773 | if (activeCount == 0 && _cachedBytesLoaded == _cachedBytesTotal) { | ||
| 774 | _completeHandler(null); | ||
| 775 | } | ||
| 776 | } | ||
| 777 | } | ||
| 778 | |||
| 779 | /** @private **/ | ||
| 780 | override protected function _progressHandler(event:Event):void { | ||
| 781 | if (_dispatchProgress) { | ||
| 782 | var bl:uint = _cachedBytesLoaded; | ||
| 783 | var bt:uint = _cachedBytesTotal; | ||
| 784 | _calculateProgress(); | ||
| 785 | if ((_cachedBytesLoaded != _cachedBytesTotal || _status != LoaderStatus.LOADING) && (bl != _cachedBytesLoaded || bt != _cachedBytesTotal)) { //note: added _status != LoaderStatus.LOADING because it's possible for all the children to load independently (without the LoaderMax actively loading), so in those cases, the progress would never reach 1 since LoaderMax's _completeHandler() won't be called to dispatch the final PROGRESS event. | ||
| 786 | dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this)); | ||
| 787 | } | ||
| 788 | } else { | ||
| 789 | _cacheIsDirty = true; | ||
| 790 | } | ||
| 791 | if (_dispatchChildProgress) { | ||
| 792 | dispatchEvent(new LoaderEvent(LoaderEvent.CHILD_PROGRESS, event.target)); | ||
| 793 | } | ||
| 794 | } | ||
| 795 | |||
| 796 | /** @private **/ | ||
| 797 | protected function _disposeHandler(event:Event):void { | ||
| 798 | _removeLoader(LoaderCore(event.target), false); | ||
| 799 | } | ||
| 800 | |||
| 801 | /** @private **/ | ||
| 802 | protected function _prioritizeHandler(event:Event):void { | ||
| 803 | var loader:LoaderCore = event.target as LoaderCore; | ||
| 804 | _loaders.splice(getChildIndex(loader), 1); | ||
| 805 | _loaders.unshift(loader); | ||
| 806 | if (_status == LoaderStatus.LOADING && loader.status <= LoaderStatus.LOADING && !(loader in _activeLoaders)) { | ||
| 807 | _cancelActiveLoaders(); | ||
| 808 | var prevMaxConnections:uint = this.maxConnections; | ||
| 809 | this.maxConnections = 1; | ||
| 810 | _loadNext(null); | ||
| 811 | this.maxConnections = prevMaxConnections; | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | |||
| 816 | //---- STATIC METHODS ---------------------------------------------------------------------------- | ||
| 817 | |||
| 818 | /** | ||
| 819 | * Activates particular loader classes (like ImageLoader, SWFLoader, etc.) so that they can be | ||
| 820 | * recognized inside the <code>parse()</code> method and XMLLoader. For example, if <code>LoaderMax.parse("image.jpg")</code> | ||
| 821 | * is called without first activating ImageLoader (like <code>LoaderMax.activate([ImageLoader])</code>), | ||
| 822 | * it wouldn't properly recognize the ".jpg" extension and return the necessary ImageLoader instance. Likewise, | ||
| 823 | * without activating ImageLoader first, XMLLoader wouldn't be able to recognize <code><ImageLoader></code> | ||
| 824 | * nodes nested inside an XML file. You only need to activate() the loader classes once in your swf. | ||
| 825 | * For example:<br /><br /><code> | ||
| 826 | * | ||
| 827 | * LoaderMax.activate([ImageLoader, SWFLoader, MP3Loader, DataLoader, CSSLoader]);</code><br /><br /> | ||
| 828 | * | ||
| 829 | * The reason all loaders aren't activated by default is to conserve file size. <br /><br /> | ||
| 830 | * | ||
| 831 | * @param loaderClasses An array of loader classes, like <code>[ImageLoader, SWFLoader, MP3Loader]</code>. | ||
| 832 | */ | ||
| 833 | public static function activate(loaderClasses:Array):void { | ||
| 834 | //no need to do anything - we just want to force the classes to get compiled in the swf. Each one calls the _activateClass() method in LoaderCore on its own. | ||
| 835 | } | ||
| 836 | |||
| 837 | /** | ||
| 838 | * Searches <strong>ALL</code> loaders to find one based on its name or url. For example:<br /><br /><code> | ||
| 839 | * | ||
| 840 | * var loader:ImageLoader = LoaderMax.getLoader("myPhoto1") as ImageLoader;<br /><br /></code> | ||
| 841 | * | ||
| 842 | * @param nameOrURL The name or url associated with the loader that should be found. | ||
| 843 | * @return The loader associated with the name or url. | ||
| 844 | */ | ||
| 845 | public static function getLoader(nameOrURL:String):* { | ||
| 846 | return (_globalRootLoader != null) ? _globalRootLoader.getLoader(nameOrURL) : null; | ||
| 847 | } | ||
| 848 | |||
| 849 | /** | ||
| 850 | * Searches <strong>ALL</strong> loaders to find content based on its name or url. For example:<br /><br /><code> | ||
| 851 | * | ||
| 852 | * var image:Bitmap = LoaderMax.getContent("myPhoto1");<br /><br /></code> | ||
| 853 | * | ||
| 854 | * @param nameOrURL The name or url associated with the loader whose content should be found. | ||
| 855 | * @return The content that was loaded by the loader which varies by the type of loader: | ||
| 856 | * <ul> | ||
| 857 | * <li><strong> ImageLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the ImageLoader's <code>rawContent</code> (a <code>flash.display.Bitmap</code> unless script access was denied in which case <code>rawContent</code> will be a <code>flash.display.Loader</code> to avoid security errors).</li> | ||
| 858 | * <li><strong> SWFLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the SWFLoader's <code>rawContent</code> (the swf's <code>root</code> DisplayObject unless script access was denied in which case <code>rawContent</code> will be a <code>flash.display.Loader</code> to avoid security errors).</li> | ||
| 859 | * <li><strong> VideoLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the VideoLoader's <code>rawContent</code> (a Video object to which the NetStream was attached).</li> | ||
| 860 | * <li><strong> XMLLoader </strong> - XML</li> | ||
| 861 | * <li><strong> DataLoader </strong> | ||
| 862 | * <ul> | ||
| 863 | * <li><code>String</code> if the DataLoader's <code>format</code> vars property is <code>"text"</code> (the default).</li> | ||
| 864 | * <li><code>flash.utils.ByteArray</code> if the DataLoader's <code>format</code> vars property is <code>"binary"</code>.</li> | ||
| 865 | * <li><code>flash.net.URLVariables</code> if the DataLoader's <code>format</code> vars property is <code>"variables"</code>.</li> | ||
| 866 | * </ul></li> | ||
| 867 | * <li><strong> CSSLoader </strong> - <code>flash.text.StyleSheet</code></li> | ||
| 868 | * <li><strong> MP3Loader </strong> - <code>flash.media.Sound</code></li> | ||
| 869 | * <li><strong> LoaderMax </strong> - an array containing the content objects from each of its child loaders.</li> | ||
| 870 | * </ul> | ||
| 871 | */ | ||
| 872 | public static function getContent(nameOrURL:String):* { | ||
| 873 | return (_globalRootLoader != null) ? _globalRootLoader.getContent(nameOrURL) : null; | ||
| 874 | } | ||
| 875 | |||
| 876 | /** | ||
| 877 | * Immediately prioritizes a loader inside any LoaderMax instances that contain it, | ||
| 878 | * forcing it to the top position in their queue and optionally calls <code>load()</code> | ||
| 879 | * immediately as well. If one of its parent LoaderMax instances is currently loading a | ||
| 880 | * different loader, that one will be temporarily cancelled. <br /><br /> | ||
| 881 | * | ||
| 882 | * By contrast, when <code>load()</code> is called, it doesn't change the loader's position/index | ||
| 883 | * in any LoaderMax queues. For example, if a LoaderMax is working on loading the first object in | ||
| 884 | * its queue, you can call load() on the 20th item and it will honor your request without | ||
| 885 | * changing its index in the queue. <code>prioritize()</code>, however, affects the position | ||
| 886 | * in the queue and optionally loads it immediately as well.<br /><br /> | ||
| 887 | * | ||
| 888 | * So even if your LoaderMax hasn't begun loading yet, you could <code>prioritize(false)</code> | ||
| 889 | * a loader and it will rise to the top of all LoaderMax instances to which it belongs, but not | ||
| 890 | * start loading yet. If the goal is to load something immediately, you can just use the | ||
| 891 | * <code>load()</code> method.<br /><br /> | ||
| 892 | * | ||
| 893 | * For example, to immediately prioritize the loader named "myPhoto1":<br /><br /><code> | ||
| 894 | * | ||
| 895 | * LoaderMax.prioritize("myPhoto1");</code> | ||
| 896 | * | ||
| 897 | * @param nameOrURL The name or url associated with the loader that should be prioritized | ||
| 898 | * @param loadNow If <code>true</code> (the default), the loader will start loading immediately (otherwise it is simply placed at the top the queue in any LoaderMax instances to which it belongs). | ||
| 899 | * @return The loader that was prioritized. If no loader was found, <code>null</code> is returned. | ||
| 900 | */ | ||
| 901 | public static function prioritize(nameOrURL:String, loadNow:Boolean=true):LoaderCore { | ||
| 902 | var loader:LoaderCore = getLoader(nameOrURL); | ||
| 903 | if (loader != null) { | ||
| 904 | loader.prioritize(loadNow); | ||
| 905 | } | ||
| 906 | return loader; | ||
| 907 | } | ||
| 908 | |||
| 909 | |||
| 910 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 911 | |||
| 912 | /** Number of child loaders currently contained in the LoaderMax instance (does not include deeply nested loaders - only children). To get the quantity of all children including nested ones, use <code>getChildren(true, true).length</code> @see #getChildren() **/ | ||
| 913 | public function get numChildren():uint { | ||
| 914 | return _loaders.length; | ||
| 915 | } | ||
| 916 | |||
| 917 | /** An array containing the content of each loader inside the LoaderMax **/ | ||
| 918 | override public function get content():* { | ||
| 919 | var a:Array = []; | ||
| 920 | var i:int = _loaders.length; | ||
| 921 | while (--i > -1) { | ||
| 922 | a[i] = LoaderCore(_loaders[i]).content; | ||
| 923 | } | ||
| 924 | return a; | ||
| 925 | } | ||
| 926 | |||
| 927 | /** @inheritDoc **/ | ||
| 928 | override public function get status():int { | ||
| 929 | //if the status of children changed after the LoaderMax completed, we need to make adjustments to the LoaderMax's status. | ||
| 930 | if (_status == LoaderStatus.COMPLETED) { | ||
| 931 | var statusCounts:Array = [0, 0, 0, 0, 0, 0]; //store the counts of each type of status (index 0 is for READY, 1 is LOADING, 2 is COMPLETE, etc. | ||
| 932 | var i:int = _loaders.length; | ||
| 933 | while (--i > -1) { | ||
| 934 | statusCounts[LoaderCore(_loaders[i]).status]++; | ||
| 935 | } | ||
| 936 | if ((!this.skipFailed && statusCounts[4] != 0) || (!this.skipPaused && statusCounts[3] != 0)) { | ||
| 937 | _status = LoaderStatus.FAILED; | ||
| 938 | } else if (statusCounts[0] + statusCounts[1] != 0) { | ||
| 939 | _status = LoaderStatus.READY; | ||
| 940 | _cacheIsDirty = true; | ||
| 941 | } | ||
| 942 | } | ||
| 943 | return _status; | ||
| 944 | } | ||
| 945 | |||
| 946 | /** @inheritDoc **/ | ||
| 947 | override public function get auditedSize():Boolean { | ||
| 948 | var maxStatus:int = (this.skipPaused) ? LoaderStatus.COMPLETED : LoaderStatus.PAUSED; | ||
| 949 | var i:int = _loaders.length; | ||
| 950 | while (--i > -1) { | ||
| 951 | if (!LoaderCore(_loaders[i]).auditedSize && LoaderCore(_loaders[i]).status <= maxStatus) { | ||
| 952 | return false; | ||
| 953 | } | ||
| 954 | } | ||
| 955 | return true; | ||
| 956 | } | ||
| 957 | |||
| 958 | /** | ||
| 959 | * An unweighted value between 0 and 1 indicating the overall loading progress of the LoaderMax - this calculation does not concern | ||
| 960 | * itself whatsoever with <code>bytesLoaded</code> and <code>bytesTotal</code> but rather the ratio of the children that are loaded | ||
| 961 | * (all having equal weight). Therefore, <code>rawProgress</code> is a more crude way of measuring the overall loading progress and | ||
| 962 | * isn't weighted in terms of file size the way that <code>progress</code> is. The only benefit of using <code>rawProgress</code> instead | ||
| 963 | * of <code>progress</code> is that there is never a risk of the value moving backwards the way it can with <code>progress</code> | ||
| 964 | * when child loaders have inaccurately low estimatedByte values (before LoaderMax audits the file size values). <br /><br /> | ||
| 965 | * | ||
| 966 | * For example, let's say you have a LoaderMax that contains 3 ImageLoaders: the first two must load images that are 25k each and the | ||
| 967 | * 3rd one must load an image that's 450k. After the first two ImageLoaders finish, the LoaderMax's <code>progress</code> property would | ||
| 968 | * report 0.1 (50k loaded out of 500k total) whereas the <code>rawProgress</code> would report 0.66 (2 loaders out of 3 total have completed). | ||
| 969 | * However, if you set the <code>estimatedBytes</code> of all of the ImageLoaders in this example to 25600 (25k) and set the LoaderMax's | ||
| 970 | * <code>auditSize</code> to <code>false</code>, the <code>progress</code> would read about 0.66 after the first two ImageLoaders complete | ||
| 971 | * (it still thinks they're all 25k) and then when the 3rd one starts loading and LoaderMax finds out that it's 450k, the <code>bytesTotal</code> | ||
| 972 | * would automatically adjust and the <code>progress</code> would jump backwards to 0.1 (which correctly reflects the weighted progress). | ||
| 973 | * Of course a solution would be to more accurately set the <code>estimatedBytes</code> and/or leave <code>auditSize true</code> in the | ||
| 974 | * LoaderMax, but <code>rawProgress</code> can be useful if those solutions are undesirable in your scenario and you need to avoid any | ||
| 975 | * backwards adjustment of a preloader progress bar or some other interface element.<br /><br /> | ||
| 976 | * | ||
| 977 | * @see #progress | ||
| 978 | **/ | ||
| 979 | public function get rawProgress():Number { | ||
| 980 | var loaded:Number = 0; | ||
| 981 | var total:uint = 0; | ||
| 982 | var status:int; | ||
| 983 | var i:int = _loaders.length; | ||
| 984 | while (--i > -1) { | ||
| 985 | status = LoaderCore(_loaders[i]).status; | ||
| 986 | if (status != LoaderStatus.DISPOSED && !(status == LoaderStatus.PAUSED && this.skipPaused) && !(status == LoaderStatus.FAILED && this.skipFailed)) { | ||
| 987 | total++; | ||
| 988 | loaded += LoaderCore(_loaders[i]).progress; | ||
| 989 | } | ||
| 990 | } | ||
| 991 | return (total == 0) ? 0 : loaded / total; | ||
| 992 | } | ||
| 993 | |||
| 994 | } | ||
| 995 | } |
| 1 | /** | ||
| 2 | * VERSION: 1.0 | ||
| 3 | * DATE: 2010-06-16 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | /** | ||
| 9 | * Defines status values for loaders. <br /><br /> | ||
| 10 | * | ||
| 11 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 12 | * | ||
| 13 | * @author Jack Doyle, jack@greensock.com | ||
| 14 | */ | ||
| 15 | public class LoaderStatus { | ||
| 16 | |||
| 17 | /** The loader is ready to load and has not completed yet. **/ | ||
| 18 | public static const READY:int = 0; | ||
| 19 | /** The loader is actively in the process of loading. **/ | ||
| 20 | public static const LOADING:int = 1; | ||
| 21 | /** The loader has completed. **/ | ||
| 22 | public static const COMPLETED:int = 2; | ||
| 23 | /** The loader is paused. **/ | ||
| 24 | public static const PAUSED:int = 3; | ||
| 25 | /** The loader failed and did not load properly. **/ | ||
| 26 | public static const FAILED:int = 4; | ||
| 27 | /** The loader has been disposed. **/ | ||
| 28 | public static const DISPOSED:int = 5; | ||
| 29 | |||
| 30 | } | ||
| 31 | |||
| 32 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.4 | ||
| 3 | * DATE: 2010-09-10 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import com.greensock.events.LoaderEvent; | ||
| 9 | import com.greensock.loading.core.LoaderItem; | ||
| 10 | |||
| 11 | import flash.display.Shape; | ||
| 12 | import flash.events.Event; | ||
| 13 | import flash.events.ProgressEvent; | ||
| 14 | import flash.media.Sound; | ||
| 15 | import flash.media.SoundChannel; | ||
| 16 | import flash.media.SoundLoaderContext; | ||
| 17 | import flash.media.SoundTransform; | ||
| 18 | |||
| 19 | /** | ||
| 20 | * Loads an MP3 audio file and also provides convenient playback methods | ||
| 21 | * and properties like <code>pauseSound(), playSound(), gotoSoundTime(), playProgress, volume, | ||
| 22 | * soundPaused, duration, </code> and <code>soundTime</code>. An MP3Loader will dispatch useful events | ||
| 23 | * like <code>SOUND_COMPLETE, SOUND_PAUSE, SOUND_PLAY</code>, and <code>PLAY_PROGRESS</code> in addition | ||
| 24 | * to the typical loader events, making it easy to hook up your own control interface. It packs a | ||
| 25 | * surprising amount of functionality into a very small amount of kb. <br /><br /> | ||
| 26 | * | ||
| 27 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 28 | * The following special properties can be passed into the MP3Loader constructor via its <code>vars</code> | ||
| 29 | * parameter which can be either a generic object or an <code><a href="data/MP3LoaderVars.html">MP3LoaderVars</a></code> object:<br /> | ||
| 30 | * <ul> | ||
| 31 | * <li><strong> name : String</strong> - A name that is used to identify the MP3Loader instance. This name can be fed to the <code>find()</code> method or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 32 | * <li><strong> autoPlay : Boolean</strong> - By default the MP3 will begin playing immediately when enough of the file has buffered, but to prevent it from autoPlaying, set <code>autoPlay</code> to <code>false</code>.</li> | ||
| 33 | * <li><strong> repeat : int</strong> - Number of times that the mp3 should repeat. To repeat indefinitely, use -1. Default is 0.</li> | ||
| 34 | * <li><strong> volume : Number</strong> - A value between 0 and 1 indicating the volume at which the sound should play when the MP3Loader's controls are used to play the sound, like <code>playSound()</code> or when <code>autoPlay</code> is <code>true</code> (default volume is 1).</li> | ||
| 35 | * <li><strong> initThreshold : uint</strong> - The minimum number of <code>bytesLoaded</code> to wait for before the <code>LoaderEvent.INIT</code> event is dispatched - the higher the number the more accurate the <code>duration</code> estimate will be when the INIT event is dispatched (the default value is 102400 which is 100k). The MP3's duration cannot be determined with 100% accuracy until it has completely loaded, but it is estimated with more and more accuracy as the file loads.</code>.</li> | ||
| 36 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 37 | * <li><strong> context : SoundLoaderContext</strong> - To control things like the buffer time and whether or not a policy file is checked, define a <code>SoundLoaderContext</code> object. The default context is null. See Adobe's SoundLoaderContext documentation for details.</li> | ||
| 38 | * <li><strong> noCache : Boolean</strong> - If <code>noCache</code> is <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>getLoader()</code> or <code>getContent()</code> by url and when you're running locally)</li> | ||
| 39 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader will be inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 40 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this MP3Loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:MP3Loader = new MP3Loader("audio.mp3", {name:"audio", requireWithRoot:this.root});</code></li> | ||
| 41 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 42 | * | ||
| 43 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 44 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 45 | * <li><strong> onInit : Function</strong> - A handler function for <code>Event.INIT</code> events which will be dispatched when the <code>bytesLoaded</code> exceeds the <code>initThreshold</code> (100k by default) and the MP3 has streamed enough of its content to identify the ID3 meta data. Make sure your onInit function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 46 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 47 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 48 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 49 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 50 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 51 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 52 | * </ul><br /> | ||
| 53 | * | ||
| 54 | * <strong>Note:</strong> Using a <code><a href="data/MP3LoaderVars.html">MP3LoaderVars</a></code> instance | ||
| 55 | * instead of a generic object to define your <code>vars</code> is a bit more verbose but provides | ||
| 56 | * code hinting and improved debugging because it enforces strict data typing. Use whichever one you prefer.<br /><br /> | ||
| 57 | * | ||
| 58 | * <code>content</code> data type: <strong><code>flash.media.Sound</code></strong><br /><br /> | ||
| 59 | * | ||
| 60 | * <strong>NOTE:</strong> To avoid garbage collection issues in the Flash player, the <code>Sound</code> | ||
| 61 | * object that MP3Loader employs must get recreated internally anytime the MP3Loader is unloaded or its loading | ||
| 62 | * is cancelled, so it is best to access the <code>content</code> after the <code>COMPLETE</code> | ||
| 63 | * event has been dispatched. Otherwise, if you store a reference to the MP3Loader's <code>content</code> | ||
| 64 | * before or during a load and it gets cancelled or unloaded for some reason, the <code>Sound</code> object | ||
| 65 | * won't be the one into which the MP3 is eventually loaded.<br /><br /> | ||
| 66 | * | ||
| 67 | * @example Example AS3 code:<listing version="3.0"> | ||
| 68 | import com.greensock.~~; | ||
| 69 | import com.greensock.loading.~~; | ||
| 70 | import com.greensock.events.LoaderEvent; | ||
| 71 | |||
| 72 | //create a MP3Loader that will begin playing immediately when it loads | ||
| 73 | var sound:MP3Loader = new MP3Loader("mp3/audio.mp3", {name:"audio", autoPlay:true, repeat:3, estimatedBytes:9500}); | ||
| 74 | |||
| 75 | //begin loading | ||
| 76 | sound.load(); | ||
| 77 | |||
| 78 | //add a CLICK listener to a button that causes the sound to toggle its paused state. | ||
| 79 | button.addEventListener(MouseEvent.CLICK, toggleSound); | ||
| 80 | function toggleSound(event:MouseEvent):void { | ||
| 81 | sound.soundPaused = !sound.soundPaused; | ||
| 82 | } | ||
| 83 | |||
| 84 | //or you could put the MP3Loader into a LoaderMax queue. Create one first... | ||
| 85 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 86 | |||
| 87 | //append the MP3Loader and then several other loaders | ||
| 88 | queue.append( sound ); | ||
| 89 | queue.append( new XMLLoader("xml/doc.xml", {name:"xmlDoc", estimatedBytes:425}) ); | ||
| 90 | queue.append( new ImageLoader("img/photo1.jpg", {name:"photo1", estimatedBytes:3500}) ); | ||
| 91 | |||
| 92 | //start loading | ||
| 93 | queue.load(); | ||
| 94 | |||
| 95 | function progressHandler(event:LoaderEvent):void { | ||
| 96 | trace("progress: " + event.target.progress); | ||
| 97 | } | ||
| 98 | |||
| 99 | function completeHandler(event:LoaderEvent):void { | ||
| 100 | trace(event.target + " is complete!"); | ||
| 101 | } | ||
| 102 | |||
| 103 | function errorHandler(event:LoaderEvent):void { | ||
| 104 | trace("error occured with " + event.target + ": " + event.text); | ||
| 105 | } | ||
| 106 | </listing> | ||
| 107 | * | ||
| 108 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 109 | * | ||
| 110 | * @see com.greensock.loading.data.MP3LoaderVars | ||
| 111 | * | ||
| 112 | * @author Jack Doyle, jack@greensock.com | ||
| 113 | */ | ||
| 114 | public class MP3Loader extends LoaderItem { | ||
| 115 | /** @private **/ | ||
| 116 | private static var _classActivated:Boolean = _activateClass("MP3Loader", MP3Loader, "mp3"); | ||
| 117 | /** @private for ENTER_FRAME listeners **/ | ||
| 118 | private static var _shape:Shape = new Shape(); | ||
| 119 | |||
| 120 | /** Event type constant for when the sound completes. **/ | ||
| 121 | public static const SOUND_COMPLETE:String="soundComplete"; | ||
| 122 | /** Event type constant for when the sound is paused. **/ | ||
| 123 | public static const SOUND_PAUSE:String="soundPause"; | ||
| 124 | /** Event type constant for when the sound begins or resumes playing. **/ | ||
| 125 | public static const SOUND_PLAY:String="soundPlay"; | ||
| 126 | /** Event type constant for when the playback progresses (only dispatched when the sound is playing). **/ | ||
| 127 | public static const PLAY_PROGRESS:String="playProgress"; | ||
| 128 | |||
| 129 | /** @private **/ | ||
| 130 | protected var _sound:Sound; | ||
| 131 | /** @private **/ | ||
| 132 | protected var _context:SoundLoaderContext; | ||
| 133 | /** @private **/ | ||
| 134 | protected var _soundPaused:Boolean; | ||
| 135 | /** @private **/ | ||
| 136 | protected var _soundComplete:Boolean; | ||
| 137 | /** @private **/ | ||
| 138 | protected var _position:Number; | ||
| 139 | /** @private **/ | ||
| 140 | protected var _soundTransform:SoundTransform; | ||
| 141 | /** @private **/ | ||
| 142 | protected var _duration:Number; | ||
| 143 | /** @private Improves performance **/ | ||
| 144 | protected var _dispatchPlayProgress:Boolean; | ||
| 145 | /** @private -1 = not initted, no ID3 data, 0 = received ID3 data, 1 = fully initted **/ | ||
| 146 | protected var _initPhase:int; | ||
| 147 | |||
| 148 | /** The minimum number of <code>bytesLoaded</code> to wait for before the <code>LoaderEvent.INIT</code> event is dispatched - the higher the number the more accurate the <code>duration</code> estimate will be when the INIT event is dispatched (the default value is 102400 which is 100k). The MP3's duration cannot be determined with 100% accuracy until it has completely loaded, but it is estimated with more and more accuracy as the file loads. **/ | ||
| 149 | public var initThreshold:uint; | ||
| 150 | /** The SoundChannel object that results from the most recent <code>playSound()</code> call (or when <code>autoPlay</code> is <code>true</code> in the constructor's <code>vars</code> parameter). Typically there isn't much reason to use this directly. Instead, use the MP3Loader's controls like <code>playSound(), pauseSound(), gotoSoundTime(), playProgress, duration, soundTime</code>, etc. **/ | ||
| 151 | public var channel:SoundChannel; | ||
| 152 | |||
| 153 | /** | ||
| 154 | * Constructor. | ||
| 155 | * | ||
| 156 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content | ||
| 157 | * @param vars An object containing optional configuration details. For example: <code>new MP3Loader("mp3/audio.mp3", {name:"audio", autoPlay:true, onComplete:completeHandler, onProgress:progressHandler})</code>.<br /><br /> | ||
| 158 | * | ||
| 159 | * The following special properties can be passed into the constructor via the <code>vars</code> parameter | ||
| 160 | * which can be either a generic object or an <code><a href="data/MP3LoaderVars.html">MP3LoaderVars</a></code> object:<br /> | ||
| 161 | * <ul> | ||
| 162 | * <li><strong> name : String</strong> - A name that is used to identify the MP3Loader instance. This name can be fed to the <code>find()</code> method or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 163 | * <li><strong> autoPlay : Boolean</strong> - By default the MP3 will begin playing immediately when enough of the file has buffered, but to prevent it from autoPlaying, set <code>autoPlay</code> to <code>false</code>.</li> | ||
| 164 | * <li><strong> repeat : int</strong> - Number of times that the mp3 should repeat. To repeat indefinitely, use -1. Default is 0.</li> | ||
| 165 | * <li><strong> volume : Number</strong> - A value between 0 and 1 indicating the volume at which the sound should play (default is 1).</li> | ||
| 166 | * <li><strong> initThreshold : uint</strong> - The minimum number of <code>bytesLoaded</code> to wait for before the <code>LoaderEvent.INIT</code> event is dispatched - the higher the number the more accurate the <code>duration</code> estimate will be when the INIT event is dispatched (the default value is 102400 which is 100k). The MP3's duration cannot be determined with 100% accuracy until it has completely loaded, but it is estimated with more and more accuracy as the file loads.</code>.</li> | ||
| 167 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 168 | * <li><strong> context : SoundLoaderContext</strong> - To control things like the buffer time and whether or not a policy file is checked, define a <code>SoundLoaderContext</code> object. The default context is null. See Adobe's SoundLoaderContext documentation for details.</li> | ||
| 169 | * <li><strong> noCache : Boolean</strong> - If <code>noCache</code> is <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>getLoader()</code> or <code>getContent()</code> by url and when you're running locally)</li> | ||
| 170 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader will be inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 171 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this MP3Loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:MP3Loader = new MP3Loader("audio.mp3", {name:"audio", requireWithRoot:this.root});</code></li> | ||
| 172 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 173 | * | ||
| 174 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 175 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 176 | * <li><strong> onInit : Function</strong> - A handler function for <code>Event.INIT</code> events which will be dispatched when the <code>bytesLoaded</code> exceeds the <code>initThreshold</code> (100k by default) and the MP3 has streamed enough of its content to identify the ID3 meta data. Make sure your onInit function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 177 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 178 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 179 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 180 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 181 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 182 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 183 | * </ul> | ||
| 184 | * @see com.greensock.loading.data.MP3LoaderVars | ||
| 185 | */ | ||
| 186 | public function MP3Loader(urlOrRequest:*, vars:Object=null) { | ||
| 187 | super(urlOrRequest, vars); | ||
| 188 | _type = "MP3Loader"; | ||
| 189 | _position = 0; | ||
| 190 | _duration = 0; | ||
| 191 | _soundPaused = true; | ||
| 192 | _soundTransform = new SoundTransform(("volume" in this.vars) ? this.vars.volume : 1); | ||
| 193 | this.initThreshold = ("initThreshold" in this.vars) ? uint(this.vars.initThreshold) : 102400; | ||
| 194 | _initSound(); | ||
| 195 | } | ||
| 196 | |||
| 197 | /** @private **/ | ||
| 198 | protected function _initSound():void { | ||
| 199 | if (_sound != null) { | ||
| 200 | try { | ||
| 201 | _sound.close(); | ||
| 202 | } catch (error:Error) { | ||
| 203 | |||
| 204 | } | ||
| 205 | _sound.removeEventListener(ProgressEvent.PROGRESS, _progressHandler); | ||
| 206 | _sound.removeEventListener(Event.COMPLETE, _completeHandler); | ||
| 207 | _sound.removeEventListener("ioError", _failHandler); | ||
| 208 | _sound.removeEventListener(Event.ID3, _id3Handler); | ||
| 209 | } | ||
| 210 | _initPhase = -1; | ||
| 211 | _sound = _content = new Sound(); | ||
| 212 | _sound.addEventListener(ProgressEvent.PROGRESS, _progressHandler, false, 0, true); | ||
| 213 | _sound.addEventListener(Event.COMPLETE, _completeHandler, false, 0, true); | ||
| 214 | _sound.addEventListener("ioError", _failHandler, false, 0, true); | ||
| 215 | _sound.addEventListener(Event.ID3, _id3Handler, false, 0, true); | ||
| 216 | } | ||
| 217 | |||
| 218 | /** @private **/ | ||
| 219 | override protected function _load():void { | ||
| 220 | _context = (this.vars.context is SoundLoaderContext) ? this.vars.context : new SoundLoaderContext(3000); | ||
| 221 | _prepRequest(); | ||
| 222 | _soundComplete = false; | ||
| 223 | _initPhase = -1; | ||
| 224 | _position = 0; | ||
| 225 | _duration = 0; | ||
| 226 | try { | ||
| 227 | _sound.load(_request, _context); | ||
| 228 | if (this.vars.autoPlay != false) { | ||
| 229 | playSound(); | ||
| 230 | } | ||
| 231 | } catch (error:Error) { | ||
| 232 | _errorHandler(new LoaderEvent(LoaderEvent.ERROR, this, error.message)); | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 236 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 237 | override protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 238 | this.pauseSound(); | ||
| 239 | _initSound(); | ||
| 240 | _position = 0; | ||
| 241 | _duration = 0; | ||
| 242 | _soundComplete = false; | ||
| 243 | super._dump(scrubLevel, newStatus); | ||
| 244 | _content = _sound; | ||
| 245 | } | ||
| 246 | |||
| 247 | /** | ||
| 248 | * Plays the sound. | ||
| 249 | * | ||
| 250 | * @param event An optional Event which simply makes it easier to use the method as a handler for mouse clicks or other events. | ||
| 251 | * @return The SoundChannel object created by the play() | ||
| 252 | * | ||
| 253 | * @see #soundPaused | ||
| 254 | * @see #pauseSound() | ||
| 255 | * @see #gotoSoundTime() | ||
| 256 | * @see #soundTime | ||
| 257 | * @see #playProgress | ||
| 258 | **/ | ||
| 259 | public function playSound(event:Event=null):SoundChannel { | ||
| 260 | this.soundPaused = false; | ||
| 261 | return this.channel; | ||
| 262 | } | ||
| 263 | |||
| 264 | /** | ||
| 265 | * Pauses playback of the sound. | ||
| 266 | * | ||
| 267 | * @param event An optional Event which simply makes it easier to use the method as a handler for mouse clicks or other events. | ||
| 268 | * | ||
| 269 | * @see #soundPaused | ||
| 270 | * @see #gotoSoundTime() | ||
| 271 | * @see #playSound() | ||
| 272 | * @see #soundTime | ||
| 273 | * @see #playProgress | ||
| 274 | **/ | ||
| 275 | public function pauseSound(event:Event=null):void { | ||
| 276 | this.soundPaused = true; | ||
| 277 | } | ||
| 278 | |||
| 279 | /** | ||
| 280 | * Attempts to jump to a certain time in the sound. If the sound hasn't downloaded enough to get to | ||
| 281 | * the new time, it will get as close as possible. | ||
| 282 | * For example, to jump to exactly 3-seconds into the sound and play from there:<br /><br /><code> | ||
| 283 | * | ||
| 284 | * loader.gotoSoundTime(3, true);<br /><br /></code> | ||
| 285 | * | ||
| 286 | * @param time The time (in seconds, offset from the very beginning) at which to place the virtual playhead in the sound. | ||
| 287 | * @param forcePlay If <code>true</code>, the sound will resume playback immediately after seeking to the new position. | ||
| 288 | * @see #pauseSound() | ||
| 289 | * @see #playSound() | ||
| 290 | * @see #soundTime | ||
| 291 | * @see #playProgress | ||
| 292 | **/ | ||
| 293 | public function gotoSoundTime(time:Number, forcePlay:Boolean=false):void { | ||
| 294 | if (time > _duration) { | ||
| 295 | time = _duration; | ||
| 296 | } | ||
| 297 | _position = time * 1000; | ||
| 298 | _soundComplete = false; | ||
| 299 | |||
| 300 | if (!_soundPaused || forcePlay) { | ||
| 301 | if (this.channel != null) { | ||
| 302 | this.channel.removeEventListener(Event.SOUND_COMPLETE, _soundCompleteHandler); | ||
| 303 | this.channel.stop(); | ||
| 304 | } | ||
| 305 | this.channel = _sound.play(_position, ((this.vars.repeat == -1) ? 9999999 : uint(this.vars.repeat) + 1), _soundTransform); | ||
| 306 | this.channel.addEventListener(Event.SOUND_COMPLETE, _soundCompleteHandler); | ||
| 307 | if (_soundPaused) { | ||
| 308 | _shape.addEventListener(Event.ENTER_FRAME, _enterFrameHandler, false, 0, true); | ||
| 309 | _soundPaused = false; | ||
| 310 | dispatchEvent(new LoaderEvent(SOUND_PLAY, this)); | ||
| 311 | } | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 316 | |||
| 317 | /** @private **/ | ||
| 318 | protected function _id3Handler(event:Event):void { | ||
| 319 | if (_sound.bytesLoaded > this.initThreshold) { | ||
| 320 | _initPhase = 1; | ||
| 321 | dispatchEvent(new LoaderEvent(LoaderEvent.INIT, this)); | ||
| 322 | } else { | ||
| 323 | _initPhase = 0; | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | /** @private **/ | ||
| 328 | override protected function _progressHandler(event:Event):void { | ||
| 329 | if (_initPhase == 0 && _sound.bytesLoaded > this.initThreshold) { | ||
| 330 | _initPhase = 1; | ||
| 331 | dispatchEvent(new LoaderEvent(LoaderEvent.INIT, this)); | ||
| 332 | } | ||
| 333 | super._progressHandler(event); | ||
| 334 | } | ||
| 335 | |||
| 336 | /** @private **/ | ||
| 337 | protected function _soundCompleteHandler(event:Event):void { | ||
| 338 | _soundComplete = true; | ||
| 339 | this.soundPaused = true; | ||
| 340 | _position = _duration * 1000; | ||
| 341 | _enterFrameHandler(null); | ||
| 342 | dispatchEvent(new LoaderEvent(SOUND_COMPLETE, this)); | ||
| 343 | } | ||
| 344 | |||
| 345 | /** @private **/ | ||
| 346 | protected function _enterFrameHandler(event:Event):void { | ||
| 347 | if (_dispatchPlayProgress) { | ||
| 348 | dispatchEvent(new LoaderEvent(PLAY_PROGRESS, this)); | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | /** @inheritDoc **/ | ||
| 353 | override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void { | ||
| 354 | if (type == PLAY_PROGRESS) { | ||
| 355 | _dispatchPlayProgress = true; | ||
| 356 | } | ||
| 357 | super.addEventListener(type, listener, useCapture, priority, useWeakReference); | ||
| 358 | } | ||
| 359 | |||
| 360 | /** @private **/ | ||
| 361 | override protected function _completeHandler(event:Event=null):void { | ||
| 362 | _duration = _sound.length / 1000; | ||
| 363 | if (_initPhase != 1) { | ||
| 364 | _initPhase = 1; | ||
| 365 | dispatchEvent(new LoaderEvent(LoaderEvent.INIT, this)); | ||
| 366 | } | ||
| 367 | super._completeHandler(event); | ||
| 368 | } | ||
| 369 | |||
| 370 | |||
| 371 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 372 | |||
| 373 | /** The playback status of the sound: <code>true</code> if the sound's playback is paused, <code>false</code> if it isn't. **/ | ||
| 374 | public function get soundPaused():Boolean { | ||
| 375 | return _soundPaused; | ||
| 376 | } | ||
| 377 | public function set soundPaused(value:Boolean):void { | ||
| 378 | var changed:Boolean = Boolean(value != _soundPaused); | ||
| 379 | _soundPaused = value; | ||
| 380 | if (!changed) { | ||
| 381 | return; | ||
| 382 | } | ||
| 383 | if (_soundPaused) { | ||
| 384 | if (this.channel != null) { | ||
| 385 | _position = this.channel.position; | ||
| 386 | this.channel.removeEventListener(Event.SOUND_COMPLETE, _soundCompleteHandler); | ||
| 387 | _shape.removeEventListener(Event.ENTER_FRAME, _enterFrameHandler); | ||
| 388 | this.channel.stop(); | ||
| 389 | } | ||
| 390 | } else { | ||
| 391 | this.channel = _sound.play(_position, ((this.vars.repeat == -1) ? 9999999 : uint(this.vars.repeat) + 1), _soundTransform); | ||
| 392 | this.channel.addEventListener(Event.SOUND_COMPLETE, _soundCompleteHandler); | ||
| 393 | _shape.addEventListener(Event.ENTER_FRAME, _enterFrameHandler, false, 0, true); | ||
| 394 | } | ||
| 395 | dispatchEvent(new LoaderEvent(((_soundPaused) ? SOUND_PAUSE : SOUND_PLAY), this)); | ||
| 396 | } | ||
| 397 | |||
| 398 | /** A value between 0 and 1 describing the playback progress where 0 means the virtual playhead is at the very beginning of the sound, 0.5 means it is at the halfway point and 1 means it is at the end of the sound. **/ | ||
| 399 | public function get playProgress():Number { | ||
| 400 | return (_soundComplete) ? 1 : (this.soundTime / this.duration); | ||
| 401 | } | ||
| 402 | public function set playProgress(value:Number):void { | ||
| 403 | if (this.duration != 0) { | ||
| 404 | gotoSoundTime((value * _duration), !_soundPaused); | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | /** The volume of the sound (a value between 0 and 1). **/ | ||
| 409 | public function get volume():Number { | ||
| 410 | return _soundTransform.volume; | ||
| 411 | } | ||
| 412 | public function set volume(value:Number):void { | ||
| 413 | _soundTransform.volume = value; | ||
| 414 | if (this.channel != null) { | ||
| 415 | this.channel.soundTransform = _soundTransform; | ||
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | /** The time (in seconds) at which the virtual playhead is positioned on the sound. For example, if the virtual playhead is currently at the 3-second position (3 seconds from the beginning), this value would be 3. **/ | ||
| 420 | public function get soundTime():Number { | ||
| 421 | return (!_soundPaused && this.channel != null) ? this.channel.position / 1000 : _position / 1000; | ||
| 422 | } | ||
| 423 | public function set soundTime(value:Number):void { | ||
| 424 | gotoSoundTime(value, !_soundPaused); | ||
| 425 | } | ||
| 426 | |||
| 427 | /** The duration (in seconds) of the sound. This value cannot be determined with 100% accuracy until the file has completely loaded, but it is estimated with more and more accuracy as the file loads. **/ | ||
| 428 | public function get duration():Number { | ||
| 429 | if (_sound.bytesLoaded < _sound.bytesTotal) { | ||
| 430 | _duration = (_sound.length / 1000) / (_sound.bytesLoaded / _sound.bytesTotal); | ||
| 431 | } | ||
| 432 | return _duration; | ||
| 433 | } | ||
| 434 | |||
| 435 | } | ||
| 436 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.4 | ||
| 3 | * DATE: 2010-09-14 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import com.greensock.events.LoaderEvent; | ||
| 9 | import com.greensock.loading.core.DisplayObjectLoader; | ||
| 10 | import com.greensock.loading.core.LoaderCore; | ||
| 11 | |||
| 12 | import flash.display.AVM1Movie; | ||
| 13 | import flash.display.DisplayObject; | ||
| 14 | import flash.display.DisplayObjectContainer; | ||
| 15 | import flash.display.MovieClip; | ||
| 16 | import flash.events.Event; | ||
| 17 | import flash.events.ProgressEvent; | ||
| 18 | import flash.media.SoundTransform; | ||
| 19 | import flash.utils.getQualifiedClassName; | ||
| 20 | |||
| 21 | /** Dispatched when any loader that the SWFLoader discovered in the subloaded swf dispatches an OPEN event. **/ | ||
| 22 | [Event(name="childOpen", type="com.greensock.events.LoaderEvent")] | ||
| 23 | /** Dispatched when any loader that the SWFLoader discovered in the subloaded swf dispatches a PROGRESS event. **/ | ||
| 24 | [Event(name="childProgress", type="com.greensock.events.LoaderEvent")] | ||
| 25 | /** Dispatched when any loader that the SWFLoader discovered in the subloaded swf dispatches a COMPLETE event. **/ | ||
| 26 | [Event(name="childComplete", type="com.greensock.events.LoaderEvent")] | ||
| 27 | /** Dispatched when any loader that the SWFLoader discovered in the subloaded swf dispatches a FAIL event. **/ | ||
| 28 | [Event(name="childFail", type="com.greensock.events.LoaderEvent")] | ||
| 29 | /** Dispatched when any loader that the SWFLoader discovered in the subloaded swf dispatches a CANCEL event. **/ | ||
| 30 | [Event(name="childCancel", type="com.greensock.events.LoaderEvent")] | ||
| 31 | /** Dispatched when the loader is denied script access to the swf which can happen if it is loaded from another domain and there's no crossdomain.xml file in place. **/ | ||
| 32 | [Event(name="scriptAccessDenied", type="com.greensock.events.LoaderEvent")] | ||
| 33 | /** Dispatched when the loader's <code>httpStatus</code> value changes. **/ | ||
| 34 | [Event(name="httpStatus", type="com.greensock.events.LoaderEvent")] | ||
| 35 | /** Dispatched when the loader experiences a SECURITY_ERROR while loading or auditing its size. **/ | ||
| 36 | [Event(name="securityError", type="com.greensock.events.LoaderEvent")] | ||
| 37 | /** | ||
| 38 | * Loads a swf file and automatically searches for active loaders in that swf that have | ||
| 39 | * the <code>requireWithRoot</code> vars property set to that swf's <code>root</code>. If it finds any, | ||
| 40 | * it will factor those loaders' progress into its own progress and not dispatch its | ||
| 41 | * <code>COMPLETE</code> event until the nested loaders have finished. <br /><br /> | ||
| 42 | * | ||
| 43 | * The SWFLoader's <code>content</code> refers to a <code>ContentDisplay</code> (a Sprite) that | ||
| 44 | * is created immediately so that you can position/scale/rotate it or add ROLL_OVER/ROLL_OUT/CLICK listeners | ||
| 45 | * before (or while) the swf loads. Use the SWFLoader's <code>content</code> property to get the ContentDisplay | ||
| 46 | * Sprite, or use the <code>rawContent</code> property to get the actual root of the loaded swf file itself. | ||
| 47 | * If a <code>container</code> is defined in the <code>vars</code> object, the ContentDisplay will | ||
| 48 | * immediately be added to that container). <br /><br /> | ||
| 49 | * | ||
| 50 | * If you define a <code>width</code> and <code>height</code>, it will draw a rectangle | ||
| 51 | * in the ContentDisplay so that interactive events fire appropriately (rollovers, etc.) and width/height/bounds | ||
| 52 | * get reported accurately. This rectangle is invisible by default, but you can control its color and alpha | ||
| 53 | * with the <code>bgColor</code> and <code>bgAlpha</code> properties. When the swf loads, it will be | ||
| 54 | * added to the ContentDisplay at index 0 with <code>addChildAt()</code> and scaled to fit the width/height according to | ||
| 55 | * the <code>scaleMode</code>. These are all optional features - you do not need to define a | ||
| 56 | * <code>width</code> or <code>height</code> in which case the swf will load at its native size. | ||
| 57 | * See the list below for all the special properties that can be passed through the <code>vars</code> | ||
| 58 | * parameter but don't let the list overwhelm you - these are all optional and they are intended to make | ||
| 59 | * your job as a developer much easier.<br /><br /> | ||
| 60 | * | ||
| 61 | * By default, the SWFLoader will attempt to load the swf in a way that allows full script | ||
| 62 | * access (same SecurityDomain and child ApplicationDomain). However, if a security error is thrown because | ||
| 63 | * the swf is being loaded from another domain and the appropriate crossdomain.xml file isn't in place | ||
| 64 | * to grant access, the SWFLoader will automatically adjust the default LoaderContext so that it falls | ||
| 65 | * back to the more restricted mode which will have the following effect: | ||
| 66 | * <ul> | ||
| 67 | * <li>A <code>LoaderEvent.SCRIPT_ACCESS_DENIED</code> event will be dispatched and the <code>scriptAccessDenied</code> property of the SWFLoader will be set to <code>true</code>. You can check this value before performing any restricted operations on the content like BitmapData.draw().</li> | ||
| 68 | * <li>Other LoaderMax-related loaders inside the swf will not be recognized or integrated into the SWFLoader's overall progress.</li> | ||
| 69 | * <li>A <code>Loader</code> instance will be added to the <code>ContentDisplay</code> Sprite instead of the swf's <code>root</code>.</li> | ||
| 70 | * <li>The <code>getClass()</code> and <code>getSWFChild()</code> methods will always return <code>null</code>.</li> | ||
| 71 | * <li>BitmapData operations like <code>draw()</code> will not be able to be performed on the swf.</li> | ||
| 72 | * </ul> | ||
| 73 | * | ||
| 74 | * If the loaded swf is an <code>AVM1Movie</code> (built in AS1 or AS2), <code>scriptAccessDenied</code> will be <code>true</code> | ||
| 75 | * and a <code>Loader</code> instance will be added to the <code>content</code> Sprite instead of the swf's <code>root</code>. <br /><br /> | ||
| 76 | * | ||
| 77 | * To maximize the likelihood of your swf loading without any security problems, consider taking the following steps: | ||
| 78 | * <ul> | ||
| 79 | * <li><strong>Use a crossdomain.xml file </strong> - See Adobe's docs for details, but here is an example that grants full access (put this in a crossdomain.xml file that is at the root of the remote domain):<br /> | ||
| 80 | * <?xml version="1.0" encoding="utf-8"?><br /> | ||
| 81 | * <cross-domain-policy><br /> | ||
| 82 | * <allow-access-from domain="~~" /><br /> | ||
| 83 | * </cross-domain-policy></li> | ||
| 84 | * <li>In the embed code of any HTML wrapper, set <code>AllowScriptAccess</code> to <code>"always"</code></li> | ||
| 85 | * <li>If possible, in the remote swf make sure you explicitly allow script access using something like <code>flash.system.Security.allowDomain("~~");</code></li> | ||
| 86 | * </ul><br /> | ||
| 87 | * | ||
| 88 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 89 | * The following special properties can be passed into the SWFLoader constructor via its <code>vars</code> | ||
| 90 | * parameter which can be either a generic object or an <code><a href="data/SWFLoaderVars.html">SWFLoaderVars</a></code> object:<br /> | ||
| 91 | * <ul> | ||
| 92 | * <li><strong> name : String</strong> - A name that is used to identify the SWFLoader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods. This name is also applied to the Sprite that is created to hold the swf (The SWFLoader's <code>content</code> refers to this Sprite). Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 93 | * <li><strong> container : DisplayObjectContainer</strong> - A DisplayObjectContainer into which the <code>content</code> Sprite should be added immediately.</li> | ||
| 94 | * <li><strong> width : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 95 | * <li><strong> height : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 96 | * <li><strong> centerRegistration : Boolean </strong> - if <code>true</code>, the registration point will be placed in the center of the <code>ContentDisplay</code> Sprite which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center.</li> | ||
| 97 | * <li><strong> scaleMode : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded swf will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 98 | * <ul> | ||
| 99 | * <li><code>"stretch"</code> (the default) - The swf will fill the width/height exactly.</li> | ||
| 100 | * <li><code>"proportionalInside"</code> - The swf will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 101 | * <li><code>"proportionalOutside"</code> - The swf will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height.</li> | ||
| 102 | * <li><code>"widthOnly"</code> - Only the width of the swf will be adjusted to fit.</li> | ||
| 103 | * <li><code>"heightOnly"</code> - Only the height of the swf will be adjusted to fit.</li> | ||
| 104 | * <li><code>"none"</code> - No scaling of the swf will occur.</li> | ||
| 105 | * </ul></li> | ||
| 106 | * <li><strong> hAlign : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>hAlign</code> determines how the swf is horizontally aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 107 | * <ul> | ||
| 108 | * <li><code>"center"</code> (the default) - The swf will be centered horizontally in the area</li> | ||
| 109 | * <li><code>"left"</code> - The swf will be aligned with the left side of the area</li> | ||
| 110 | * <li><code>"right"</code> - The swf will be aligned with the right side of the area</li> | ||
| 111 | * </ul></li> | ||
| 112 | * <li><strong> vAlign : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>vAlign</code> determines how the swf is vertically aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 113 | * <ul> | ||
| 114 | * <li><code>"center"</code> (the default) - The swf will be centered vertically in the area</li> | ||
| 115 | * <li><code>"top"</code> - The swf will be aligned with the top of the area</li> | ||
| 116 | * <li><code>"bottom"</code> - The swf will be aligned with the bottom of the area</li> | ||
| 117 | * </ul></li> | ||
| 118 | * <li><strong> crop : Boolean</strong> - When a <code>width</code> and <code>height</code> are defined, setting <code>crop</code> to <code>true</code> will cause the swf to be cropped within that area (by applying a <code>scrollRect</code> for maximum performance) based on its native size (not the bounding box of the swf's current contents). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> or <code>"none"</code> or when the swf contains objects that are positioned off-stage. Any parts of the swf that exceed the dimensions defined by <code>width</code> and <code>height</code> are visually chopped off. Use the <code>hAlign</code> and <code>vAlign</code> special properties to control the vertical and horizontal alignment within the cropped area.</li> | ||
| 119 | * <li><strong> x : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>x</code> property (for positioning on the stage).</li> | ||
| 120 | * <li><strong> y : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>y</code> property (for positioning on the stage).</li> | ||
| 121 | * <li><strong> scaleX : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleX</code> property.</li> | ||
| 122 | * <li><strong> scaleY : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleY</code> property.</li> | ||
| 123 | * <li><strong> rotation : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>rotation</code> property.</li> | ||
| 124 | * <li><strong> alpha : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>alpha</code> property.</li> | ||
| 125 | * <li><strong> visible : Boolean</strong> - Sets the <code>ContentDisplay</code>'s <code>visible</code> property.</li> | ||
| 126 | * <li><strong> blendMode : String</strong> - Sets the <code>ContentDisplay</code>'s <code>blendMode</code> property.</li> | ||
| 127 | * <li><strong> autoPlay : Boolean</strong> - If <code>autoPlay</code> is <code>true</code> (the default), the swf will begin playing immediately when the <code>INIT</code> event fires. To prevent this behavior, set <code>autoPlay</code> to <code>false</code> which will also mute the swf until the SWFLoader completes.</li> | ||
| 128 | * <li><strong> bgColor : uint </strong> - When a <code>width</code> and <code>height</code> are defined, a rectangle will be drawn inside the <code>ContentDisplay</code> Sprite immediately in order to ease the development process. It is transparent by default, but you may define a <code>bgAlpha</code> if you prefer.</li> | ||
| 129 | * <li><strong> bgAlpha : Number </strong> - Controls the alpha of the rectangle that is drawn when a <code>width</code> and <code>height</code> are defined.</li> | ||
| 130 | * <li><strong> context : LoaderContext</strong> - To control things like the ApplicationDomain, SecurityDomain, and whether or not a policy file is checked, define a <code>LoaderContext</code> object. The default context is null when running locally and <code>new LoaderContext(true, new ApplicationDomain(ApplicationDomain.currentDomain), SecurityDomain.currentDomain)</code> when running remotely in order to avoid common security sandbox errors (see Adobe's LoaderContext documentation for details and precautions). Please make sure that if you load swfs from another domain that you have a crossdomain.xml file installed on that remote server that grants your swf access rights (see Adobe's docs for crossdomain.xml details). Again, if you want to impose security restrictions on the loaded swf, please define your own LoaderContext.</li> | ||
| 131 | * <li><strong> integrateProgress : Boolean</strong> - By default, a SWFLoader instance will automatically look for LoaderMax loaders in the swf when it initializes. Every loader found with a <code>requireWithRoot</code> parameter set to that swf's <code>root</code> will be integrated into the SWFLoader's overall progress. The SWFLoader's <code>COMPLETE</code> event won't fire until all such loaders are also complete. If you prefer NOT to integrate the subloading loaders into the SWFLoader's overall progress, set <code>integrateProgress</code> to <code>false</code>.</li> | ||
| 132 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 133 | * <li><strong> noCache : Boolean</strong> - If <code>noCache</code> is <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>getLoader()</code> or <code>getContent()</code> by url and when you're running locally)</li> | ||
| 134 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the swf initializes and has been analyzed enough to determine the size of any nested loaders that were found inside the swf with their <code>requireWithRoot</code> set to that swf's <code>root</code>, it will adjust the <code>bytesTotal</code> accordingly. Setting <code>estimatedBytes</code> is optional, but it provides a way to avoid situations where the <code>progress</code> and <code>bytesTotal</code> values jump around as SWFLoader recognizes nested loaders in the swf and audits their size. The <code>estimatedBytes</code> value should include all nested loaders as well, so if your swf file itself is 2000 bytes and it has 3 nested ImageLoaders, each loading a 2000-byte image, your SWFLoader's <code>estimatedBytes</code> should be 8000. The more accurate the value, the more accurate the loaders' overall progress will be.</li> | ||
| 135 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this SWFLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:SWFLoader = new SWFLoader("subload.swf", {name:"subloadSWF", requireWithRoot:this.root});</code></li> | ||
| 136 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 137 | * | ||
| 138 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 139 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 140 | * <li><strong> onInit : Function</strong> - A handler function for <code>LoaderEvent.INIT</code> events which are called when the swf has streamed enough of its content to render the first frame and determine if there are any required LoaderMax-related loaders recognized. It also adds the swf to the ContentDisplay Sprite at this point. Make sure your onInit function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 141 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 142 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 143 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 144 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 145 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 146 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 147 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 148 | * <li><strong> onSecurityError : Function</strong> - A handler function for <code>LoaderEvent.SECURITY_ERROR</code> events which onError handles as well, so you can use that as more of a catch-all whereas onSecurityError is specifically for SECURITY_ERROR events. Make sure your onSecurityError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 149 | * <li><strong> onScriptAccessDenied : Function</strong> - A handler function for <code>LoaderMax.SCRIPT_ACCESS_DENIED</code> events which occur when the swf is loaded from another domain and no crossdomain.xml is in place to grant full script access for things like BitmapData manipulation or integration of LoaderMax data inside the swf, etc. You can also check the <code>scriptAccessDenied</code> property after the swf has loaded. Make sure your function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 150 | * <li><strong> onChildOpen : Function</strong> - A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 151 | * <li><strong> onChildProgress : Function</strong> - A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) dispatches a <code>PROGRESS</code> event. To listen for changes in the SWFLoader's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the SWFLoader, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 152 | * <li><strong> onChildComplete : Function</strong> - A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 153 | * <li><strong> onChildCancel : Function</strong> - A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 154 | * <li><strong> onChildFail : Function</strong> - A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 155 | * </ul><br /> | ||
| 156 | * | ||
| 157 | * <strong>Note:</strong> Using a <code><a href="data/SWFLoaderVars.html">SWFLoaderVars</a></code> instance | ||
| 158 | * instead of a generic object to define your <code>vars</code> is a bit more verbose but provides | ||
| 159 | * code hinting and improved debugging because it enforces strict data typing. Use whichever one you prefer.<br /><br /> | ||
| 160 | * | ||
| 161 | * <code>content</code> data type: <strong><code>com.greensock.loading.display.ContentDisplay</code></strong> (a Sprite). | ||
| 162 | * When the swf has finished loading, the <code>rawContent</code> will be added to the <code>ContentDisplay</code> | ||
| 163 | * Sprite at index 0 using <code>addChildAt()</code>. <code>rawContent</code> refers to the loaded swf's <code>root</code> | ||
| 164 | * unless unless script access is denied in which case it will be a <code>flash.display.Loader</code> (to avoid security errors).<br /><br /> | ||
| 165 | * | ||
| 166 | * @example Example AS3 code:<listing version="3.0"> | ||
| 167 | import com.greensock.~~; | ||
| 168 | import com.greensock.loading.~~; | ||
| 169 | |||
| 170 | //create a SWFLoader that will add the content to the display list at position x:50, y:100 when it has loaded: | ||
| 171 | var loader:SWFLoader = new SWFLoader("swf/main.swf", {name:"mainSWF", container:this, x:50, y:100, onInit:initHandler, estimatedBytes:9500}); | ||
| 172 | |||
| 173 | //begin loading | ||
| 174 | loader.load(); | ||
| 175 | |||
| 176 | function initHandler(event:LoaderEvent):void { | ||
| 177 | //fade the swf in as soon as it inits | ||
| 178 | TweenLite.from(event.target.content, 1, {alpha:0}); | ||
| 179 | |||
| 180 | //get a MovieClip named "phoneAnimation_mc" that's on the root of the subloaded swf | ||
| 181 | var mc:DisplayObject = loader.getSWFChild("phoneAnimation_mc"); | ||
| 182 | |||
| 183 | //find the "com.greensock.TweenLite" class that's inside the subloaded swf | ||
| 184 | var tweenClass:Class = loader.getClass("com.greensock.TweenLite"); | ||
| 185 | } | ||
| 186 | |||
| 187 | //Or you could put the SWFLoader into a LoaderMax. Create one first... | ||
| 188 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 189 | |||
| 190 | //append the SWFLoader and several other loaders | ||
| 191 | queue.append( loader ); | ||
| 192 | queue.append( new XMLLoader("xml/doc.xml", {name:"xmlDoc", estimatedBytes:425}) ); | ||
| 193 | queue.append( new ImageLoader("img/photo1.jpg", {name:"photo1", estimatedBytes:3500}) ); | ||
| 194 | |||
| 195 | //start loading | ||
| 196 | queue.load(); | ||
| 197 | |||
| 198 | function progressHandler(event:LoaderEvent):void { | ||
| 199 | trace("progress: " + event.target.progress); | ||
| 200 | } | ||
| 201 | |||
| 202 | function completeHandler(event:LoaderEvent):void { | ||
| 203 | trace(event.target + " is complete!"); | ||
| 204 | } | ||
| 205 | |||
| 206 | function errorHandler(event:LoaderEvent):void { | ||
| 207 | trace("error occured with " + event.target + ": " + event.text); | ||
| 208 | } | ||
| 209 | </listing> | ||
| 210 | * | ||
| 211 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 212 | * | ||
| 213 | * @see com.greensock.loading.data.SWFLoaderVars | ||
| 214 | * | ||
| 215 | * @author Jack Doyle, jack@greensock.com | ||
| 216 | */ | ||
| 217 | public class SWFLoader extends DisplayObjectLoader { | ||
| 218 | /** @private **/ | ||
| 219 | private static var _classActivated:Boolean = _activateClass("SWFLoader", SWFLoader, "swf"); | ||
| 220 | /** @private **/ | ||
| 221 | protected var _queue:LoaderMax; | ||
| 222 | /** @private When the INIT event is dispatched, we'll check to see if there's a runtime shared library like for TLF and we must do some backflips to accommodate it - _hasRSL will be toggled to true if we find one. **/ | ||
| 223 | protected var _hasRSL:Boolean; | ||
| 224 | /** @private **/ | ||
| 225 | protected var _rslAddedCount:uint; | ||
| 226 | |||
| 227 | /** | ||
| 228 | * Constructor | ||
| 229 | * | ||
| 230 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content | ||
| 231 | * @param vars An object containing optional configuration details. For example: <code>new SWFLoader("swf/main.swf", {name:"main", container:this, x:100, y:50, alpha:0, autoPlay:false, onComplete:completeHandler, onProgress:progressHandler})</code>.<br /><br /> | ||
| 232 | * | ||
| 233 | * The following special properties can be passed into the constructor via the <code>vars</code> parameter | ||
| 234 | * which can be either a generic object or an <code><a href="data/SWFLoaderVars.html">SWFLoaderVars</a></code> object:<br /> | ||
| 235 | * <ul> | ||
| 236 | * <li><strong> name : String</strong> - A name that is used to identify the SWFLoader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods. This name is also applied to the Sprite that is created to hold the swf (The SWFLoader's <code>content</code> refers to this Sprite). Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 237 | * <li><strong> container : DisplayObjectContainer</strong> - A DisplayObjectContainer into which the <code>content</code> Sprite should be added immediately.</li> | ||
| 238 | * <li><strong> width : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 239 | * <li><strong> height : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 240 | * <li><strong> centerRegistration : Boolean </strong> - if <code>true</code>, the registration point will be placed in the center of the <code>ContentDisplay</code> Sprite which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center.</li> | ||
| 241 | * <li><strong> scaleMode : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded swf will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 242 | * <ul> | ||
| 243 | * <li><code>"stretch"</code> (the default) - The swf will fill the width/height exactly.</li> | ||
| 244 | * <li><code>"proportionalInside"</code> - The swf will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 245 | * <li><code>"proportionalOutside"</code> - The swf will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height.</li> | ||
| 246 | * <li><code>"widthOnly"</code> - Only the width of the swf will be adjusted to fit.</li> | ||
| 247 | * <li><code>"heightOnly"</code> - Only the height of the swf will be adjusted to fit.</li> | ||
| 248 | * <li><code>"none"</code> - No scaling of the swf will occur.</li> | ||
| 249 | * </ul></li> | ||
| 250 | * <li><strong> hAlign : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>hAlign</code> determines how the swf is horizontally aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 251 | * <ul> | ||
| 252 | * <li><code>"center"</code> (the default) - The swf will be centered horizontally in the area</li> | ||
| 253 | * <li><code>"left"</code> - The swf will be aligned with the left side of the area</li> | ||
| 254 | * <li><code>"right"</code> - The swf will be aligned with the right side of the area</li> | ||
| 255 | * </ul></li> | ||
| 256 | * <li><strong> vAlign : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>vAlign</code> determines how the swf is vertically aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 257 | * <ul> | ||
| 258 | * <li><code>"center"</code> (the default) - The swf will be centered vertically in the area</li> | ||
| 259 | * <li><code>"top"</code> - The swf will be aligned with the top of the area</li> | ||
| 260 | * <li><code>"bottom"</code> - The swf will be aligned with the bottom of the area</li> | ||
| 261 | * </ul></li> | ||
| 262 | * <li><strong> crop : Boolean</strong> - When a <code>width</code> and <code>height</code> are defined, setting <code>crop</code> to <code>true</code> will cause the swf to be cropped within that area (by applying a <code>scrollRect</code> for maximum performance) based on its native size (not the bounding box of the swf's current contents). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> or <code>"none"</code> or when the swf contains objects that are positioned off-stage. Any parts of the swf that exceed the dimensions defined by <code>width</code> and <code>height</code> are visually chopped off. Use the <code>hAlign</code> and <code>vAlign</code> special properties to control the vertical and horizontal alignment within the cropped area.</li> | ||
| 263 | * <li><strong> x : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>x</code> property (for positioning on the stage).</li> | ||
| 264 | * <li><strong> y : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>y</code> property (for positioning on the stage).</li> | ||
| 265 | * <li><strong> scaleX : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleX</code> property.</li> | ||
| 266 | * <li><strong> scaleY : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleY</code> property.</li> | ||
| 267 | * <li><strong> rotation : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>rotation</code> property.</li> | ||
| 268 | * <li><strong> alpha : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>alpha</code> property.</li> | ||
| 269 | * <li><strong> visible : Boolean</strong> - Sets the <code>ContentDisplay</code>'s <code>visible</code> property.</li> | ||
| 270 | * <li><strong> blendMode : String</strong> - Sets the <code>ContentDisplay</code>'s <code>blendMode</code> property.</li> | ||
| 271 | * <li><strong> autoPlay : Boolean</strong> - If <code>autoPlay</code> is <code>true</code> (the default), the swf will begin playing immediately when the <code>INIT</code> event fires. To prevent this behavior, set <code>autoPlay</code> to <code>false</code> which will also mute the swf until the SWFLoader completes.</li> | ||
| 272 | * <li><strong> bgColor : uint </strong> - When a <code>width</code> and <code>height</code> are defined, a rectangle will be drawn inside the <code>ContentDisplay</code> Sprite immediately in order to ease the development process. It is transparent by default, but you may define a <code>bgAlpha</code> if you prefer.</li> | ||
| 273 | * <li><strong> bgAlpha : Number </strong> - Controls the alpha of the rectangle that is drawn when a <code>width</code> and <code>height</code> are defined.</li> | ||
| 274 | * <li><strong> context : LoaderContext</strong> - To control things like the ApplicationDomain, SecurityDomain, and whether or not a policy file is checked, define a <code>LoaderContext</code> object. The default context is null when running locally and <code>new LoaderContext(true, new ApplicationDomain(ApplicationDomain.currentDomain), SecurityDomain.currentDomain)</code> when running remotely in order to avoid common security sandbox errors (see Adobe's LoaderContext documentation for details and precautions). Please make sure that if you load swfs from another domain that you have a crossdomain.xml file installed on that remote server that grants your swf access rights (see Adobe's docs for crossdomain.xml details). Again, if you want to impose security restrictions on the loaded swf, please define your own LoaderContext.</li> | ||
| 275 | * <li><strong> integrateProgress : Boolean</strong> - By default, a SWFLoader instance will automatically look for LoaderMax loaders in the swf when it initializes. Every loader found with a <code>requireWithRoot</code> parameter set to that swf's <code>root</code> will be integrated into the SWFLoader's overall progress. The SWFLoader's <code>COMPLETE</code> event won't fire until all such loaders are also complete. If you prefer NOT to integrate the subloading loaders into the SWFLoader's overall progress, set <code>integrateProgress</code> to <code>false</code>.</li> | ||
| 276 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 277 | * <li><strong> noCache : Boolean</strong> - If <code>noCache</code> is <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>getLoader()</code> or <code>getContent()</code> by url and when you're running locally)</li> | ||
| 278 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the swf initializes and has been analyzed enough to determine the size of any nested loaders that were found inside the swf with their <code>requireWithRoot</code> set to that swf's <code>root</code>, it will adjust the <code>bytesTotal</code> accordingly. Setting <code>estimatedBytes</code> is optional, but it provides a way to avoid situations where the <code>progress</code> and <code>bytesTotal</code> values jump around as SWFLoader recognizes nested loaders in the swf and audits their size. The <code>estimatedBytes</code> value should include all nested loaders as well, so if your swf file itself is 2000 bytes and it has 3 nested ImageLoaders, each loading a 2000-byte image, your SWFLoader's <code>estimatedBytes</code> should be 8000. The more accurate the value, the more accurate the loaders' overall progress will be.</li> | ||
| 279 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this SWFLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:SWFLoader = new SWFLoader("subload.swf", {name:"subloadSWF", requireWithRoot:this.root});</code></li> | ||
| 280 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 281 | * | ||
| 282 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 283 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 284 | * <li><strong> onInit : Function</strong> - A handler function for <code>LoaderEvent.INIT</code> events which are called when the swf has streamed enough of its content to render the first frame and determine if there are any required LoaderMax-related loaders recognized. It also adds the swf to the ContentDisplay Sprite at this point. Make sure your onInit function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 285 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 286 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 287 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 288 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 289 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 290 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 291 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 292 | * <li><strong> onSecurityError : Function</strong> - A handler function for <code>LoaderEvent.SECURITY_ERROR</code> events which onError handles as well, so you can use that as more of a catch-all whereas onSecurityError is specifically for SECURITY_ERROR events. Make sure your onSecurityError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 293 | * <li><strong> onScriptAccessDenied : Function</strong> - A handler function for <code>LoaderMax.SCRIPT_ACCESS_DENIED</code> events which occur when the swf is loaded from another domain and no crossdomain.xml is in place to grant full script access for things like BitmapData manipulation or integration of LoaderMax data inside the swf, etc. You can also check the <code>scriptAccessDenied</code> property after the swf has loaded. Make sure your function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 294 | * <li><strong> onChildOpen : Function</strong> - A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 295 | * <li><strong> onChildProgress : Function</strong> - A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) dispatches a <code>PROGRESS</code> event. To listen for changes in the SWFLoader's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the SWFLoader, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 296 | * <li><strong> onChildComplete : Function</strong> - A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 297 | * <li><strong> onChildCancel : Function</strong> - A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 298 | * <li><strong> onChildFail : Function</strong> - A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 299 | * </ul> | ||
| 300 | * @see com.greensock.loading.data.SWFLoaderVars | ||
| 301 | */ | ||
| 302 | public function SWFLoader(urlOrRequest:*, vars:Object=null) { | ||
| 303 | super(urlOrRequest, vars); | ||
| 304 | _preferEstimatedBytesInAudit = true; | ||
| 305 | _type = "SWFLoader"; | ||
| 306 | } | ||
| 307 | |||
| 308 | /** @private **/ | ||
| 309 | override protected function _load():void { | ||
| 310 | if (_stealthMode) { | ||
| 311 | //it's already loading, so exit stealth mode (stealth mode is entered when the SWFLoader is canceled before the Loader has dispatched the INIT event - bugs in Flash cause gc problems if we try to close() or unload() a Loader between the time it starts loading and when INIT fires... | ||
| 312 | _stealthMode = false; | ||
| 313 | } else if (!_initted) { | ||
| 314 | super._load(); | ||
| 315 | } else if (_queue != null) { | ||
| 316 | _changeQueueListeners(true); | ||
| 317 | _queue.load(false); | ||
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | /** @private **/ | ||
| 322 | protected function _changeQueueListeners(add:Boolean):void { | ||
| 323 | if (_queue != null) { | ||
| 324 | var p:String; | ||
| 325 | if (add && this.vars.integrateProgress != false) { | ||
| 326 | _queue.addEventListener(LoaderEvent.COMPLETE, _completeHandler, false, 0, true); | ||
| 327 | _queue.addEventListener(LoaderEvent.PROGRESS, _progressHandler, false, 0, true); | ||
| 328 | _queue.addEventListener(LoaderEvent.FAIL, _failHandler, false, 0, true); | ||
| 329 | for (p in _listenerTypes) { | ||
| 330 | if (p != "onProgress" && p != "onInit") { | ||
| 331 | _queue.addEventListener(_listenerTypes[p], _passThroughEvent, false, 0, true); | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } else { | ||
| 335 | _queue.removeEventListener(LoaderEvent.COMPLETE, _completeHandler); | ||
| 336 | _queue.removeEventListener(LoaderEvent.PROGRESS, _progressHandler); | ||
| 337 | _queue.removeEventListener(LoaderEvent.FAIL, _failHandler); | ||
| 338 | |||
| 339 | for (p in _listenerTypes) { | ||
| 340 | if (p != "onProgress" && p != "onInit") { | ||
| 341 | _queue.removeEventListener(_listenerTypes[p], _passThroughEvent); | ||
| 342 | } | ||
| 343 | } | ||
| 344 | } | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 349 | override protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 350 | //Flash will refuse to properly unload it if the INIT event hasn't been dispatched! Technically we allow it to keep loading until _initHandler() is called where we'll unload it. | ||
| 351 | if (_status == LoaderStatus.LOADING && !_initted) { | ||
| 352 | _stealthMode = true; | ||
| 353 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 354 | return; | ||
| 355 | } | ||
| 356 | if (_initted && !_scriptAccessDenied && scrubLevel != 2) { | ||
| 357 | _stopMovieClips(_loader.content); | ||
| 358 | if (_loader.content in _rootLookup) { | ||
| 359 | _queue = LoaderMax(_rootLookup[_loader.content]); | ||
| 360 | _changeQueueListeners(false); | ||
| 361 | if (scrubLevel == 1) { | ||
| 362 | _queue.cancel(); | ||
| 363 | } else { | ||
| 364 | if (scrubLevel == 1) { | ||
| 365 | _queue.unload(); | ||
| 366 | } | ||
| 367 | _queue.dispose(); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | } | ||
| 371 | if (_stealthMode) { | ||
| 372 | try { | ||
| 373 | _loader.close(); | ||
| 374 | } catch (error:Error) { | ||
| 375 | |||
| 376 | } | ||
| 377 | } | ||
| 378 | _stealthMode = _hasRSL = false; | ||
| 379 | _cacheIsDirty = true; | ||
| 380 | if (scrubLevel >= 1) { | ||
| 381 | _queue = null; | ||
| 382 | _initted = false; | ||
| 383 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 384 | } else { | ||
| 385 | var content:* = _content; | ||
| 386 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 387 | _content = content; //super._dump() will null "_content", but if the swf has loaded but not the _queue, we should keep the content so that if resume() is called, it just starts loading the queue. | ||
| 388 | } | ||
| 389 | } | ||
| 390 | |||
| 391 | |||
| 392 | /** @private **/ | ||
| 393 | protected function _stopMovieClips(obj:DisplayObject):void { | ||
| 394 | var mc:MovieClip = obj as MovieClip; | ||
| 395 | if (mc == null) { | ||
| 396 | return; | ||
| 397 | } | ||
| 398 | mc.stop(); | ||
| 399 | var i:int = mc.numChildren; | ||
| 400 | while (--i > -1) { | ||
| 401 | _stopMovieClips(mc.getChildAt(i)); | ||
| 402 | } | ||
| 403 | } | ||
| 404 | |||
| 405 | /** @private **/ | ||
| 406 | override protected function _determineScriptAccess():void { | ||
| 407 | //don't test the BitmapData.draw() until the swf has fully loaded because it can incorrectly throw security errors in certain situations (like NetStreams that haven't started yet). | ||
| 408 | try { | ||
| 409 | var mc:DisplayObject = _loader.content; | ||
| 410 | } catch (error:Error) { | ||
| 411 | _scriptAccessDenied = true; | ||
| 412 | dispatchEvent(new LoaderEvent(LoaderEvent.SCRIPT_ACCESS_DENIED, this, error.message)); | ||
| 413 | return; | ||
| 414 | } | ||
| 415 | if (_loader.content is AVM1Movie) { | ||
| 416 | _scriptAccessDenied = true; | ||
| 417 | dispatchEvent(new LoaderEvent(LoaderEvent.SCRIPT_ACCESS_DENIED, this, "AVM1Movie denies script access")); | ||
| 418 | } | ||
| 419 | } | ||
| 420 | |||
| 421 | /** @private **/ | ||
| 422 | override protected function _calculateProgress():void { | ||
| 423 | _cachedBytesLoaded = (_stealthMode) ? 0 : _loader.contentLoaderInfo.bytesLoaded; | ||
| 424 | _cachedBytesTotal = _loader.contentLoaderInfo.bytesTotal; | ||
| 425 | if (_cachedBytesTotal < _cachedBytesLoaded || _initted) { | ||
| 426 | //In Chrome when the file exceeds a certain size and gzip is enabled on the server, Adobe's Loader reports bytesTotal as 0!!! | ||
| 427 | //and in Firefox, if gzip was enabled, on very small files the Loader's bytesLoaded would never quite reach the bytesTotal even after the COMPLETE event fired! | ||
| 428 | _cachedBytesTotal = _cachedBytesLoaded; | ||
| 429 | } | ||
| 430 | if (this.vars.integrateProgress == false) { | ||
| 431 | // do nothing | ||
| 432 | } else if (_queue != null && (uint(this.vars.estimatedBytes) < _cachedBytesLoaded || _queue.auditedSize)) { //make sure that estimatedBytes is prioritized until the _queue has audited its size successfully! | ||
| 433 | if (_queue.status <= LoaderStatus.COMPLETED) { | ||
| 434 | _cachedBytesLoaded += _queue.bytesLoaded; | ||
| 435 | _cachedBytesTotal += _queue.bytesTotal; | ||
| 436 | } | ||
| 437 | } else if (uint(this.vars.estimatedBytes) > _cachedBytesLoaded && (!_initted || (_queue != null && _queue.status <= LoaderStatus.COMPLETED && !_queue.auditedSize))) { | ||
| 438 | _cachedBytesTotal = uint(this.vars.estimatedBytes); | ||
| 439 | } | ||
| 440 | if ((_hasRSL && _content == null) || (!_initted && _cachedBytesLoaded == _cachedBytesTotal)) { | ||
| 441 | _cachedBytesLoaded = int(_cachedBytesLoaded * 0.99); //don't allow the progress to hit 1 yet | ||
| 442 | } | ||
| 443 | _cacheIsDirty = false; | ||
| 444 | } | ||
| 445 | |||
| 446 | /** @private **/ | ||
| 447 | protected function _checkRequiredLoaders():void { | ||
| 448 | if (_queue == null && this.vars.integrateProgress != false && !_scriptAccessDenied) { | ||
| 449 | _queue = _rootLookup[_loader.content]; | ||
| 450 | if (_queue != null) { | ||
| 451 | _changeQueueListeners(true); | ||
| 452 | _queue.load(false); | ||
| 453 | _cacheIsDirty = true; | ||
| 454 | } | ||
| 455 | } | ||
| 456 | } | ||
| 457 | |||
| 458 | /** | ||
| 459 | * Searches the loaded swf (and any of its subloaded swfs that were loaded using SWFLoader) for a particular | ||
| 460 | * class by name. For example, if the swf contains a class named "com.greensock.TweenLite", you can get a | ||
| 461 | * reference to that class like:<br /><br /><code> | ||
| 462 | * | ||
| 463 | * var tweenLite:Class = loader.getClass("com.greensock.TweenLite");<br /> | ||
| 464 | * //then you can create an instance of TweenLite like:<br /> | ||
| 465 | * var tween:Object = new tweenLite(mc, 1, {x:100});<br /></code> | ||
| 466 | * | ||
| 467 | * @param className The full name of the class, like "com.greensock.TweenLite". | ||
| 468 | * @return The class associated with the <code>className</code> | ||
| 469 | */ | ||
| 470 | public function getClass(className:String):Class { | ||
| 471 | if (_content == null || _scriptAccessDenied) { | ||
| 472 | return null; | ||
| 473 | } | ||
| 474 | var result:Object = _content.loaderInfo.applicationDomain.getDefinition(className); | ||
| 475 | if (result != null) { | ||
| 476 | return result as Class; | ||
| 477 | } else if (_queue != null) { | ||
| 478 | var loaders:Array = _queue.getChildren(true, true); | ||
| 479 | var i:int = loaders.length; | ||
| 480 | while (--i > -1) { | ||
| 481 | if (loaders[i] is SWFLoader) { | ||
| 482 | result = (loaders[i] as SWFLoader).getClass(className); | ||
| 483 | if (result != null) { | ||
| 484 | return result as Class; | ||
| 485 | } | ||
| 486 | } | ||
| 487 | } | ||
| 488 | } | ||
| 489 | return null; | ||
| 490 | } | ||
| 491 | |||
| 492 | /** | ||
| 493 | * Finds a DisplayObject that's on the <code>root</code> of the loaded SWF by name. For example, | ||
| 494 | * you could put a MovieClip with an instance name of "phoneAnimation_mc" on the stage (along with | ||
| 495 | * any other objects of course) and then when you load that swf you could use | ||
| 496 | * <code>loader.getSWFChild("phoneAnimation_mc")</code> to get that MovieClip. It would be | ||
| 497 | * similar to doing <code>(loader.rawContent as DisplayObjectContainer).getChildByName("phoneAnimation_mc")</code> | ||
| 498 | * but in a more concise way that doesn't require checking to see if the rawContent is null. <code>getSWFChild()</code> | ||
| 499 | * will return <code>null</code> if the content hasn't loaded yet or if <code>scriptAccessDenied</code> is <code>true</code>. | ||
| 500 | * | ||
| 501 | * @param name The name of the child DisplayObject that is located at the <code>root</code> of the swf. | ||
| 502 | * @return The DisplayObject with the specified name. Returns <code>null</code> if the content hasn't loaded yet or if <code>scriptAccessDenied</code> is <code>true</code>. | ||
| 503 | */ | ||
| 504 | public function getSWFChild(name:String):DisplayObject { | ||
| 505 | return (!_scriptAccessDenied && _content is DisplayObjectContainer) ? DisplayObjectContainer(_content).getChildByName(name) : null; | ||
| 506 | } | ||
| 507 | |||
| 508 | /** | ||
| 509 | * @private | ||
| 510 | * Finds a particular loader inside any active LoaderMax instances that were discovered in the subloaded swf | ||
| 511 | * which had their <code>requireWithRoot</code> set to the swf's root. This is only useful in situations | ||
| 512 | * where the swf contains other loaders that are required. | ||
| 513 | * | ||
| 514 | * @param nameOrURL The name or url associated with the loader that should be found. | ||
| 515 | * @return The loader associated with the name or url. Returns <code>null</code> if none were found. | ||
| 516 | */ | ||
| 517 | public function getLoader(nameOrURL:String):* { | ||
| 518 | return (_queue != null) ? _queue.getLoader(nameOrURL) : null; | ||
| 519 | } | ||
| 520 | |||
| 521 | /** | ||
| 522 | * @private | ||
| 523 | * Finds a particular loader's content from inside any active LoaderMax instances that were discovered in the | ||
| 524 | * subloaded swf which had their <code>requireWithRoot</code> set to the swf's root. This is only useful | ||
| 525 | * in situations where the swf contains other loaders that are required. | ||
| 526 | * | ||
| 527 | * @param nameOrURL The name or url associated with the loader whose content should be found. | ||
| 528 | * @return The content associated with the name or url. Returns <code>null</code> if none was found. | ||
| 529 | */ | ||
| 530 | public function getContent(nameOrURL:String):* { | ||
| 531 | if (nameOrURL == this.name || nameOrURL == _url) { | ||
| 532 | return this.content; | ||
| 533 | } | ||
| 534 | var loader:LoaderCore = this.getLoader(nameOrURL); | ||
| 535 | return (loader != null) ? loader.content : null; | ||
| 536 | } | ||
| 537 | |||
| 538 | /** @private **/ | ||
| 539 | public function getChildren(includeNested:Boolean=false, omitLoaderMaxes:Boolean=false):Array { | ||
| 540 | return (_queue != null) ? _queue.getChildren(includeNested, omitLoaderMaxes) : []; | ||
| 541 | } | ||
| 542 | |||
| 543 | |||
| 544 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 545 | |||
| 546 | /** @private **/ | ||
| 547 | override protected function _initHandler(event:Event):void { | ||
| 548 | //if the SWFLoader was cancelled before _initHandler() was called, Flash will refuse to properly unload it, so we allow it to continue but check the status here and _dump() if necessary. | ||
| 549 | if (_stealthMode) { | ||
| 550 | _initted = true; | ||
| 551 | _dump(1, _status, true); | ||
| 552 | return; | ||
| 553 | } | ||
| 554 | |||
| 555 | //swfs with TLF use their own funky preloader system that causes problems, so we need to work around them here... | ||
| 556 | _hasRSL = false; | ||
| 557 | try { | ||
| 558 | var tempContent:DisplayObject = _loader.content; | ||
| 559 | var className:String = getQualifiedClassName(tempContent); | ||
| 560 | if (className.substr(-13) == "__Preloader__") { | ||
| 561 | var rslPreloader:Object = tempContent["__rslPreloader"]; | ||
| 562 | if (rslPreloader != null) { | ||
| 563 | className = getQualifiedClassName(rslPreloader); | ||
| 564 | if (className == "fl.rsl::RSLPreloader") { | ||
| 565 | _hasRSL = true; | ||
| 566 | _rslAddedCount = 0; | ||
| 567 | tempContent.addEventListener(Event.ADDED, _rslAddedHandler); | ||
| 568 | } | ||
| 569 | } | ||
| 570 | } | ||
| 571 | } catch (error:Error) { | ||
| 572 | |||
| 573 | } | ||
| 574 | if (!_hasRSL) { | ||
| 575 | _init(); | ||
| 576 | } | ||
| 577 | } | ||
| 578 | |||
| 579 | /** @private **/ | ||
| 580 | protected function _init():void { | ||
| 581 | _determineScriptAccess(); | ||
| 582 | if (!_scriptAccessDenied) { | ||
| 583 | if (!_hasRSL) { | ||
| 584 | _content = _loader.content; | ||
| 585 | } | ||
| 586 | if (_content != null) { | ||
| 587 | if (this.vars.autoPlay == false && _content is MovieClip) { | ||
| 588 | var st:SoundTransform = _content.soundTransform; | ||
| 589 | st.volume = 0; //just make sure you can't hear any sounds as it's loading in the background. | ||
| 590 | _content.soundTransform = st; | ||
| 591 | _content.stop(); | ||
| 592 | } | ||
| 593 | _checkRequiredLoaders(); | ||
| 594 | } | ||
| 595 | } else { | ||
| 596 | _content = _loader; | ||
| 597 | } | ||
| 598 | super._initHandler(null); | ||
| 599 | } | ||
| 600 | |||
| 601 | /** @private Works around bug - see http://kb2.adobe.com/cps/838/cpsid_83812.html **/ | ||
| 602 | protected function _rslAddedHandler(event:Event):void { | ||
| 603 | // check to ensure this was actually something added to the _loader.content | ||
| 604 | if (event.target is DisplayObject && event.currentTarget is DisplayObjectContainer && event.target.parent == event.currentTarget) { | ||
| 605 | _rslAddedCount++; | ||
| 606 | } | ||
| 607 | // the first thing added will be the loader animation swf - ignore that | ||
| 608 | if (_rslAddedCount > 1) { | ||
| 609 | event.currentTarget.removeEventListener(Event.ADDED, _rslAddedHandler); | ||
| 610 | if (_status == LoaderStatus.LOADING) { | ||
| 611 | _content = event.target; | ||
| 612 | _init(); | ||
| 613 | _calculateProgress(); | ||
| 614 | dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this)); | ||
| 615 | _completeHandler(null); | ||
| 616 | } | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 620 | /** @private **/ | ||
| 621 | override protected function _passThroughEvent(event:Event):void { | ||
| 622 | if (event.target != _queue) { | ||
| 623 | super._passThroughEvent(event); | ||
| 624 | } | ||
| 625 | } | ||
| 626 | |||
| 627 | /** @private **/ | ||
| 628 | override protected function _progressHandler(event:Event):void { | ||
| 629 | if (_status == LoaderStatus.LOADING) { | ||
| 630 | if (_queue == null && _initted) { | ||
| 631 | _checkRequiredLoaders(); | ||
| 632 | } | ||
| 633 | if (_dispatchProgress) { | ||
| 634 | var bl:uint = _cachedBytesLoaded; | ||
| 635 | var bt:uint = _cachedBytesTotal; | ||
| 636 | _calculateProgress(); | ||
| 637 | if (_cachedBytesLoaded != _cachedBytesTotal && (bl != _cachedBytesLoaded || bt != _cachedBytesTotal)) { | ||
| 638 | dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this)); | ||
| 639 | } | ||
| 640 | } else { | ||
| 641 | _cacheIsDirty = true; | ||
| 642 | } | ||
| 643 | } | ||
| 644 | } | ||
| 645 | |||
| 646 | /** @private **/ | ||
| 647 | override protected function _completeHandler(event:Event=null):void { | ||
| 648 | _checkRequiredLoaders(); | ||
| 649 | _calculateProgress(); | ||
| 650 | if (this.progress == 1) { | ||
| 651 | if (!_scriptAccessDenied && this.vars.autoPlay == false && _content is MovieClip) { | ||
| 652 | var st:SoundTransform = _content.soundTransform; | ||
| 653 | st.volume = 1; | ||
| 654 | _content.soundTransform = st; | ||
| 655 | } | ||
| 656 | _changeQueueListeners(false); | ||
| 657 | super._determineScriptAccess(); //now do the BitmapData.draw() test. | ||
| 658 | super._completeHandler(event); | ||
| 659 | } | ||
| 660 | } | ||
| 661 | |||
| 662 | |||
| 663 | } | ||
| 664 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.3 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import com.greensock.loading.core.LoaderItem; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | import flash.display.LoaderInfo; | ||
| 12 | import flash.events.Event; | ||
| 13 | import flash.events.ProgressEvent; | ||
| 14 | /** | ||
| 15 | * Tracks the loading progress of the swf in which the loader resides (basically a simple tool for tracking | ||
| 16 | * the <code>loaderInfo</code>'s progress). SelfLoader is only useful in situations where you want to factor | ||
| 17 | * the current swf's loading progress into a LoaderMax queue or maybe display a progress bar for the current | ||
| 18 | * swf or fire an event when loading has finished.<br /><br /> | ||
| 19 | * | ||
| 20 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 21 | * The following special properties can be passed into the SelfLoader constructor via its <code>vars</code> parameter:<br /> | ||
| 22 | * <ul> | ||
| 23 | * <li><strong> name : String</strong> - A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 24 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code>. The default <code>autoDispose</code> value is <code>false</code>. | ||
| 25 | * | ||
| 26 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 27 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 28 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 29 | * </ul><br /> | ||
| 30 | * | ||
| 31 | * @example Example AS3 code:<listing version="3.0"> | ||
| 32 | import com.greensock.loading.~~; | ||
| 33 | import com.greensock.events.LoaderEvent; | ||
| 34 | |||
| 35 | //create a SelfLoader | ||
| 36 | var loader:SelfLoader = new SelfLoader(this, {name:"self", onProgress:progressHandler, onComplete:completeHandler}); | ||
| 37 | |||
| 38 | //Or you could put the SelfLoader into a LoaderMax. Create one first... | ||
| 39 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 40 | |||
| 41 | //append the SelfLoader and several other loaders | ||
| 42 | queue.append( loader ); | ||
| 43 | queue.append( new ImageLoader("images/photo1.jpg", {name:"photo1", container:this}) ); | ||
| 44 | queue.append( new SWFLoader("swf/child.swf", {name:"child", container:this, x:100, estimatedBytes:3500}) ); | ||
| 45 | |||
| 46 | //start loading the LoaderMax queue | ||
| 47 | queue.load(); | ||
| 48 | |||
| 49 | function progressHandler(event:LoaderEvent):void { | ||
| 50 | trace("progress: " + event.target.progress); | ||
| 51 | } | ||
| 52 | |||
| 53 | function completeHandler(event:LoaderEvent):void { | ||
| 54 | trace(event.target + " complete"); | ||
| 55 | } | ||
| 56 | |||
| 57 | function errorHandler(event:LoaderEvent):void { | ||
| 58 | trace("error occured with " + event.target + ": " + event.text); | ||
| 59 | } | ||
| 60 | </listing> | ||
| 61 | * | ||
| 62 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 63 | * | ||
| 64 | * @author Jack Doyle, jack@greensock.com | ||
| 65 | */ | ||
| 66 | public class SelfLoader extends LoaderItem { | ||
| 67 | /** @private **/ | ||
| 68 | protected var _loaderInfo:LoaderInfo; | ||
| 69 | |||
| 70 | /** | ||
| 71 | * Constructor | ||
| 72 | * | ||
| 73 | * @param self A DisplayObject from the main swf (it will use this DisplayObject's <code>loaderInfo</code> to track the loading progress). | ||
| 74 | * @param vars An object containing optional configuration details. For example: <code>new SelfLoader(this, {name:"self", onComplete:completeHandler, onProgress:progressHandler})</code>.<br /><br /> | ||
| 75 | * | ||
| 76 | * The following special properties can be passed into the constructor via the <code>vars</code> parameter:<br /> | ||
| 77 | * <ul> | ||
| 78 | * <li><strong> name : String</strong> - A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 79 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code>. The default <code>autoDispose</code> value is <code>false</code>. | ||
| 80 | * | ||
| 81 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 82 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 83 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 84 | * </ul> | ||
| 85 | */ | ||
| 86 | public function SelfLoader(self:DisplayObject, vars:Object=null) { | ||
| 87 | super(self.loaderInfo.url, vars); | ||
| 88 | _type = "SelfLoader"; | ||
| 89 | _loaderInfo = self.loaderInfo; | ||
| 90 | _loaderInfo.addEventListener(ProgressEvent.PROGRESS, _progressHandler, false, 0, true); | ||
| 91 | _loaderInfo.addEventListener(Event.COMPLETE, _completeHandler, false, 0, true); | ||
| 92 | _cachedBytesTotal = _loaderInfo.bytesTotal; | ||
| 93 | _cachedBytesLoaded = _loaderInfo.bytesLoaded; | ||
| 94 | _status = LoaderStatus.LOADING; | ||
| 95 | _auditedSize = true; | ||
| 96 | _content = self; | ||
| 97 | } | ||
| 98 | |||
| 99 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 100 | override protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 101 | if (scrubLevel >= 2) { | ||
| 102 | _loaderInfo.removeEventListener(ProgressEvent.PROGRESS, _progressHandler); | ||
| 103 | _loaderInfo.removeEventListener(Event.COMPLETE, _completeHandler); | ||
| 104 | } | ||
| 105 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 106 | } | ||
| 107 | |||
| 108 | } | ||
| 109 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.4 | ||
| 3 | * DATE: 2010-09-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import com.greensock.events.LoaderEvent; | ||
| 9 | import com.greensock.loading.core.LoaderItem; | ||
| 10 | import com.greensock.loading.display.ContentDisplay; | ||
| 11 | |||
| 12 | import flash.display.Sprite; | ||
| 13 | import flash.events.Event; | ||
| 14 | import flash.events.NetStatusEvent; | ||
| 15 | import flash.events.ProgressEvent; | ||
| 16 | import flash.media.SoundTransform; | ||
| 17 | import flash.media.Video; | ||
| 18 | import flash.net.NetConnection; | ||
| 19 | import flash.net.NetStream; | ||
| 20 | import flash.utils.getTimer; | ||
| 21 | |||
| 22 | /** Dispatched when the loader's <code>httpStatus</code> value changes. **/ | ||
| 23 | [Event(name="httpStatus", type="com.greensock.events.LoaderEvent")] | ||
| 24 | /** Dispatched when the <code>netStream</code> dispatches a NET_STATUS event. **/ | ||
| 25 | [Event(name="netStatus", type="flash.events.NetStatusEvent")] | ||
| 26 | /** | ||
| 27 | * Loads an FLV, F4V, or MP4 video file using a NetStream and also provides convenient playback methods | ||
| 28 | * and properties like <code>pauseVideo(), playVideo(), gotoVideoTime(), bufferProgress, playProgress, volume, | ||
| 29 | * duration, videoPaused, metaData, </code> and <code>videoTime</code>. Just like ImageLoader and SWFLoader, | ||
| 30 | * VideoLoader's <code>content</code> property refers to a <code>ContentDisplay</code> object (Sprite) that | ||
| 31 | * gets created immediately so that you can position/scale/rotate it or add ROLL_OVER/ROLL_OUT/CLICK listeners | ||
| 32 | * before (or while) the video loads. Use the VideoLoader's <code>content</code> property to get the ContentDisplay | ||
| 33 | * Sprite, or use the <code>rawContent</code> property to get the <code>Video</code> object that is used inside the | ||
| 34 | * ContentDisplay to display the video. If a <code>container</code> is defined in the <code>vars</code> object, | ||
| 35 | * the ContentDisplay will immediately be added to that container).<br /><br /> | ||
| 36 | * | ||
| 37 | * You don't need to worry about creating a NetConnection, a Video object, attaching the NetStream, or any | ||
| 38 | * of the typical hassles. VideoLoader can even scale the video into the area you specify using scaleModes | ||
| 39 | * like <code>"stretch", "proportionalInside", "proportionalOutside",</code> and more. A VideoLoader will | ||
| 40 | * dispatch useful events like <code>VIDEO_COMPLETE, VIDEO_PAUSE, VIDEO_PLAY, VIDEO_BUFFER_FULL, | ||
| 41 | * VIDEO_BUFFER_EMPTY, NET_STATUS, VIDEO_CUE_POINT</code>, and <code>PLAY_PROGRESS</code> in addition | ||
| 42 | * to the typical loader events, making it easy to hook up your own control interface. It packs a | ||
| 43 | * surprising amount of functionality into a very small amount of kb.<br /><br /> | ||
| 44 | * | ||
| 45 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 46 | * The following special properties can be passed into the VideoLoader constructor via its <code>vars</code> | ||
| 47 | * parameter which can be either a generic object or a <code><a href="data/VideoLoaderVars.html">VideoLoaderVars</a></code> object:<br /> | ||
| 48 | * <ul> | ||
| 49 | * <li><strong> name : String</strong> - A name that is used to identify the VideoLoader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 50 | * <li><strong> bufferTime : Number</strong> - The amount of time (in seconds) that should be buffered before the video can begin playing (set <code>autoPlay</code> to <code>false</code> to pause the video initially).</li> | ||
| 51 | * <li><strong> autoPlay : Boolean</strong> - By default, the video will begin playing as soon as it has been adequately buffered, but to prevent it from playing initially, set <code>autoPlay</code> to <code>false</code>.</li> | ||
| 52 | * <li><strong> smoothing : Boolean</strong> - When <code>smoothing</code> is <code>true</code> (the default), smoothing will be enabled for the video which typically leads to better scaling results.</li> | ||
| 53 | * <li><strong> container : DisplayObjectContainer</strong> - A DisplayObjectContainer into which the <code>ContentDisplay</code> should be added immediately.</li> | ||
| 54 | * <li><strong> width : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 55 | * <li><strong> height : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 56 | * <li><strong> centerRegistration : Boolean </strong> - if <code>true</code>, the registration point will be placed in the center of the <code>ContentDisplay</code> which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center.</li> | ||
| 57 | * <li><strong> scaleMode : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the video will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 58 | * <ul> | ||
| 59 | * <li><code>"stretch"</code> (the default) - The video will fill the width/height exactly.</li> | ||
| 60 | * <li><code>"proportionalInside"</code> - The video will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 61 | * <li><code>"proportionalOutside"</code> - The video will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height.</li> | ||
| 62 | * <li><code>"widthOnly"</code> - Only the width of the video will be adjusted to fit.</li> | ||
| 63 | * <li><code>"heightOnly"</code> - Only the height of the video will be adjusted to fit.</li> | ||
| 64 | * <li><code>"none"</code> - No scaling of the video will occur.</li> | ||
| 65 | * </ul></li> | ||
| 66 | * <li><strong> hAlign : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>hAlign</code> determines how the video is horizontally aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 67 | * <ul> | ||
| 68 | * <li><code>"center"</code> (the default) - The video will be centered horizontally in the area</li> | ||
| 69 | * <li><code>"left"</code> - The video will be aligned with the left side of the area</li> | ||
| 70 | * <li><code>"right"</code> - The video will be aligned with the right side of the area</li> | ||
| 71 | * </ul></li> | ||
| 72 | * <li><strong> vAlign : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>vAlign</code> determines how the video is vertically aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 73 | * <ul> | ||
| 74 | * <li><code>"center"</code> (the default) - The video will be centered vertically in the area</li> | ||
| 75 | * <li><code>"top"</code> - The video will be aligned with the top of the area</li> | ||
| 76 | * <li><code>"bottom"</code> - The video will be aligned with the bottom of the area</li> | ||
| 77 | * </ul></li> | ||
| 78 | * <li><strong> crop : Boolean</strong> - When a <code>width</code> and <code>height</code> are defined, setting <code>crop</code> to <code>true</code> will cause the video to be cropped within that area (by applying a <code>scrollRect</code> for maximum performance). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> or <code>"none"</code> so that any parts of the video that exceed the dimensions defined by <code>width</code> and <code>height</code> are visually chopped off. Use the <code>hAlign</code> and <code>vAlign</code> special properties to control the vertical and horizontal alignment within the cropped area.</li> | ||
| 79 | * <li><strong> x : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>x</code> property (for positioning on the stage).</li> | ||
| 80 | * <li><strong> y : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>y</code> property (for positioning on the stage).</li> | ||
| 81 | * <li><strong> scaleX : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleX</code> property.</li> | ||
| 82 | * <li><strong> scaleY : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleY</code> property.</li> | ||
| 83 | * <li><strong> rotation : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>rotation</code> property.</li> | ||
| 84 | * <li><strong> alpha : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>alpha</code> property.</li> | ||
| 85 | * <li><strong> visible : Boolean</strong> - Sets the <code>ContentDisplay</code>'s <code>visible</code> property.</li> | ||
| 86 | * <li><strong> blendMode : String</strong> - Sets the <code>ContentDisplay</code>'s <code>blendMode</code> property.</li> | ||
| 87 | * <li><strong> bgColor : uint </strong> - When a <code>width</code> and <code>height</code> are defined, a rectangle will be drawn inside the <code>ContentDisplay</code> immediately in order to ease the development process. It is transparent by default, but you may define a <code>bgAlpha</code> if you prefer.</li> | ||
| 88 | * <li><strong> bgAlpha : Number </strong> - Controls the alpha of the rectangle that is drawn when a <code>width</code> and <code>height</code> are defined.</li> | ||
| 89 | * <li><strong> volume : Number</strong> - A value between 0 and 1 indicating the volume at which the video should play (default is 1).</li> | ||
| 90 | * <li><strong> repeat : int</strong> - Number of times that the video should repeat. To repeat indefinitely, use -1. Default is 0.</li> | ||
| 91 | * <li><strong> checkPolicyFile : Boolean</strong> - If <code>true</code>, the VideoLoader will check for a crossdomain.xml file on the remote host (only useful when loading videos from other domains - see Adobe's docs for details about NetStream's <code>checkPolicyFile</code> property). </li> | ||
| 92 | * <li><strong> estimatedDuration : Number</strong> - Estimated duration of the video in seconds. VideoLoader will only use this value until it receives the necessary metaData from the video in order to accurately determine the video's duration. You do not need to specify an <code>estimatedDuration</code>, but doing so can help make the playProgress and some other values more accurate (until the metaData has loaded). It can also make the <code>progress/bytesLoaded/bytesTotal</code> more accurate when a <code>estimatedDuration</code> is defined, particularly in <code>bufferMode</code>.</li> | ||
| 93 | * <li><strong> deblocking : int</strong> - Indicates the type of filter applied to decoded video as part of post-processing. The default value is 0, which lets the video compressor apply a deblocking filter as needed. See Adobe's <code>flash.media.Video</code> class docs for details.</li> | ||
| 94 | * <li><strong> bufferMode : Boolean </strong> - When <code>true</code>, the loader will report its progress only in terms of the video's buffer which can be very convenient if, for example, you want to display loading progress for the video's buffer or tuck it into a LoaderMax with other loaders and allow the LoaderMax to dispatch its <code>COMPLETE</code> event when the buffer is full instead of waiting for the whole file to download. When <code>bufferMode</code> is <code>true</code>, the VideoLoader will dispatch its <code>COMPLETE</code> event when the buffer is full as opposed to waiting for the entire video to load. You can toggle the <code>bufferMode</code> anytime. Please read the full <code>bufferMode</code> property ASDoc description below for details about how it affects things like <code>bytesTotal</code>.</li> | ||
| 95 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 96 | * <li><strong> noCache : Boolean</strong> - If <code>noCache</code> is <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>getLoader()</code> or <code>getContent()</code> by url and when you're running locally)</li> | ||
| 97 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader will be inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 98 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this VideoLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:VideoLoader = new VideoLoader("myScript.php", {name:"textData", requireWithRoot:this.root});</code></li> | ||
| 99 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 100 | * | ||
| 101 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 102 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 103 | * <li><strong> onInit : Function</strong> - A handler function for <code>Event.INIT</code> events which will be called when the video's metaData has been received and the video is placed into the <code>ContentDisplay</code>. Make sure your onInit function accepts a single parameter of type <code>Event</code> (flash.events.Event).</li> | ||
| 104 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 105 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 106 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 107 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 108 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 109 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 110 | * </ul><br /> | ||
| 111 | * | ||
| 112 | * <strong>Note:</strong> Using a <code><a href="data/VideoLoaderVars.html">VideoLoaderVars</a></code> instance | ||
| 113 | * instead of a generic object to define your <code>vars</code> is a bit more verbose but provides | ||
| 114 | * code hinting and improved debugging because it enforces strict data typing. Use whichever one you prefer.<br /><br /> | ||
| 115 | * | ||
| 116 | * <strong>Note:</strong> To avoid garbage collection issues in the Flash player, the <code>netStream</code> | ||
| 117 | * object that VideoLoader employs must get recreated internally anytime the VideoLoader is unloaded or its loading | ||
| 118 | * is cancelled, so if you need to directly access the <code>netStream</code>, it is best to do so <strong>after</strong> | ||
| 119 | * the <code>COMPLETE</code> event has been dispatched. Otherwise, if you store a reference to the VideoLoader's | ||
| 120 | * <code>netStream</code> before or during a load and it gets cancelled or unloaded for some reason, it won't reference | ||
| 121 | * the one that was used to load the video.<br /><br /> | ||
| 122 | * | ||
| 123 | * @example Example AS3 code:<listing version="3.0"> | ||
| 124 | import com.greensock.loading.~~; | ||
| 125 | import com.greensock.loading.display.~~; | ||
| 126 | import com.greensock.~~; | ||
| 127 | import com.greensock.events.LoaderEvent; | ||
| 128 | |||
| 129 | //create a VideoLoader | ||
| 130 | var video:VideoLoader = new VideoLoader("assets/video.flv", {name:"myVideo", container:this, width:400, height:300, scaleMode:"proportionalInside", bgColor:0x000000, autoPlay:false, volume:0, requireWithRoot:this.root, estimatedBytes:75000}); | ||
| 131 | |||
| 132 | //start loading | ||
| 133 | video.load(); | ||
| 134 | |||
| 135 | //add a CLICK listener to a button that causes the video to toggle its paused state. | ||
| 136 | button.addEventListener(MouseEvent.CLICK, togglePause); | ||
| 137 | function togglePause(event:MouseEvent):void { | ||
| 138 | video.videoPaused = !video.videoPaused; | ||
| 139 | } | ||
| 140 | |||
| 141 | //or you could put the VideoLoader into a LoaderMax queue. Create one first... | ||
| 142 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 143 | |||
| 144 | //append the VideoLoader and several other loaders | ||
| 145 | queue.append( video ); | ||
| 146 | queue.append( new DataLoader("assets/data.txt", {name:"myText"}) ); | ||
| 147 | queue.append( new ImageLoader("assets/image1.png", {name:"myImage", estimatedBytes:3500}) ); | ||
| 148 | |||
| 149 | //start loading the LoaderMax queue | ||
| 150 | queue.load(); | ||
| 151 | |||
| 152 | function progressHandler(event:LoaderEvent):void { | ||
| 153 | trace("progress: " + event.target.progress); | ||
| 154 | } | ||
| 155 | |||
| 156 | function completeHandler(event:LoaderEvent):void { | ||
| 157 | //play the video | ||
| 158 | loader.playVideo(); | ||
| 159 | |||
| 160 | //tween the volume up to 1 over the course of 2 seconds. | ||
| 161 | TweenLite.to(loader, 2, {volume:1}); | ||
| 162 | } | ||
| 163 | |||
| 164 | function errorHandler(event:LoaderEvent):void { | ||
| 165 | trace("error occured with " + event.target + ": " + event.text); | ||
| 166 | } | ||
| 167 | </listing> | ||
| 168 | * | ||
| 169 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 170 | * | ||
| 171 | * @see com.greensock.loading.data.VideoLoaderVars | ||
| 172 | * | ||
| 173 | * @author Jack Doyle, jack@greensock.com | ||
| 174 | */ | ||
| 175 | public class VideoLoader extends LoaderItem { | ||
| 176 | /** @private **/ | ||
| 177 | private static var _classActivated:Boolean = _activateClass("VideoLoader", VideoLoader, "flv,f4v,mp4,mov"); | ||
| 178 | |||
| 179 | /** Event type constant for when the video completes. **/ | ||
| 180 | public static const VIDEO_COMPLETE:String="videoComplete"; | ||
| 181 | /** Event type constant for when the video's buffer is full. **/ | ||
| 182 | public static const VIDEO_BUFFER_FULL:String="videoBufferFull"; | ||
| 183 | /** Event type constant for when the video's buffer is empty. **/ | ||
| 184 | public static const VIDEO_BUFFER_EMPTY:String="videoBufferEmpty"; | ||
| 185 | /** Event type constant for when the video is paused. **/ | ||
| 186 | public static const VIDEO_PAUSE:String="videoPause"; | ||
| 187 | /** Event type constant for when the video begins or resumes playing. **/ | ||
| 188 | public static const VIDEO_PLAY:String="videoPlay"; | ||
| 189 | /** Event type constant for when the video reaches a cue point in the playback of the NetStream. **/ | ||
| 190 | public static const VIDEO_CUE_POINT:String="videoCuePoint"; | ||
| 191 | /** Event type constant for when the playback progresses (only dispatched when the video is playing). **/ | ||
| 192 | public static const PLAY_PROGRESS:String="playProgress"; | ||
| 193 | |||
| 194 | /** @private **/ | ||
| 195 | protected var _ns:NetStream; | ||
| 196 | /** @private **/ | ||
| 197 | protected var _nc:NetConnection; | ||
| 198 | /** @private **/ | ||
| 199 | protected var _video:Video; | ||
| 200 | /** @private **/ | ||
| 201 | protected var _sound:SoundTransform; | ||
| 202 | /** @private **/ | ||
| 203 | protected var _videoPaused:Boolean; | ||
| 204 | /** @private **/ | ||
| 205 | protected var _videoComplete:Boolean; | ||
| 206 | /** @private **/ | ||
| 207 | protected var _forceTime:Number; | ||
| 208 | /** @private **/ | ||
| 209 | protected var _duration:Number; | ||
| 210 | /** @private **/ | ||
| 211 | protected var _pauseOnBufferFull:Boolean; | ||
| 212 | /** @private **/ | ||
| 213 | protected var _volume:Number; | ||
| 214 | /** @private **/ | ||
| 215 | protected var _sprite:Sprite; | ||
| 216 | /** @private **/ | ||
| 217 | protected var _initted:Boolean; | ||
| 218 | /** @private **/ | ||
| 219 | protected var _bufferMode:Boolean; | ||
| 220 | /** @private **/ | ||
| 221 | protected var _repeatCount:uint; | ||
| 222 | /** @private **/ | ||
| 223 | protected var _bufferFull:Boolean; | ||
| 224 | /** @private **/ | ||
| 225 | protected var _dispatchPlayProgress:Boolean; | ||
| 226 | |||
| 227 | /** The metaData that was received from the video (contains information about its width, height, frame rate, etc.). See Adobe's docs for information about a NetStream's onMetaData callback. **/ | ||
| 228 | public var metaData:Object; | ||
| 229 | |||
| 230 | /** | ||
| 231 | * Constructor | ||
| 232 | * | ||
| 233 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content. | ||
| 234 | * @param vars An object containing optional configuration details. For example: <code>new VideoLoader("video/video.flv", {name:"myVideo", onComplete:completeHandler, onProgress:progressHandler})</code>.<br /><br /> | ||
| 235 | * | ||
| 236 | * The following special properties can be passed into the constructor via the <code>vars</code> parameter | ||
| 237 | * which can be either a generic object or a <code><a href="data/VideoLoaderVars.html">VideoLoaderVars</a></code> object:<br /> | ||
| 238 | * <ul> | ||
| 239 | * <li><strong> name : String</strong> - A name that is used to identify the VideoLoader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 240 | * <li><strong> bufferTime : Number</strong> - The amount of time (in seconds) that should be buffered before the video can begin playing (set <code>autoPlay</code> to <code>false</code> to pause the video initially).</li> | ||
| 241 | * <li><strong> autoPlay : Boolean</strong> - By default, the video will begin playing as soon as it has been adequately buffered, but to prevent it from playing initially, set <code>autoPlay</code> to <code>false</code>.</li> | ||
| 242 | * <li><strong> smoothing : Boolean</strong> - When <code>smoothing</code> is <code>true</code> (the default), smoothing will be enabled for the video which typically leads to better scaling results.</li> | ||
| 243 | * <li><strong> container : DisplayObjectContainer</strong> - A DisplayObjectContainer into which the <code>ContentDisplay</code> should be added immediately.</li> | ||
| 244 | * <li><strong> width : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 245 | * <li><strong> height : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY).</li> | ||
| 246 | * <li><strong> centerRegistration : Boolean </strong> - if <code>true</code>, the registration point will be placed in the center of the <code>ContentDisplay</code> which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center.</li> | ||
| 247 | * <li><strong> scaleMode : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the video will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 248 | * <ul> | ||
| 249 | * <li><code>"stretch"</code> (the default) - The video will fill the width/height exactly.</li> | ||
| 250 | * <li><code>"proportionalInside"</code> - The video will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 251 | * <li><code>"proportionalOutside"</code> - The video will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height.</li> | ||
| 252 | * <li><code>"widthOnly"</code> - Only the width of the video will be adjusted to fit.</li> | ||
| 253 | * <li><code>"heightOnly"</code> - Only the height of the video will be adjusted to fit.</li> | ||
| 254 | * <li><code>"none"</code> - No scaling of the video will occur.</li> | ||
| 255 | * </ul></li> | ||
| 256 | * <li><strong> hAlign : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>hAlign</code> determines how the video is horizontally aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 257 | * <ul> | ||
| 258 | * <li><code>"center"</code> (the default) - The video will be centered horizontally in the area</li> | ||
| 259 | * <li><code>"left"</code> - The video will be aligned with the left side of the area</li> | ||
| 260 | * <li><code>"right"</code> - The video will be aligned with the right side of the area</li> | ||
| 261 | * </ul></li> | ||
| 262 | * <li><strong> vAlign : String </strong> - When a <code>width</code> and <code>height</code> are defined, the <code>vAlign</code> determines how the video is vertically aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 263 | * <ul> | ||
| 264 | * <li><code>"center"</code> (the default) - The video will be centered vertically in the area</li> | ||
| 265 | * <li><code>"top"</code> - The video will be aligned with the top of the area</li> | ||
| 266 | * <li><code>"bottom"</code> - The video will be aligned with the bottom of the area</li> | ||
| 267 | * </ul></li> | ||
| 268 | * <li><strong> crop : Boolean</strong> - When a <code>width</code> and <code>height</code> are defined, setting <code>crop</code> to <code>true</code> will cause the video to be cropped within that area (by applying a <code>scrollRect</code> for maximum performance). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> or <code>"none"</code> so that any parts of the video that exceed the dimensions defined by <code>width</code> and <code>height</code> are visually chopped off. Use the <code>hAlign</code> and <code>vAlign</code> special properties to control the vertical and horizontal alignment within the cropped area.</li> | ||
| 269 | * <li><strong> x : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>x</code> property (for positioning on the stage).</li> | ||
| 270 | * <li><strong> y : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>y</code> property (for positioning on the stage).</li> | ||
| 271 | * <li><strong> scaleX : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleX</code> property.</li> | ||
| 272 | * <li><strong> scaleY : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>scaleY</code> property.</li> | ||
| 273 | * <li><strong> rotation : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>rotation</code> property.</li> | ||
| 274 | * <li><strong> alpha : Number</strong> - Sets the <code>ContentDisplay</code>'s <code>alpha</code> property.</li> | ||
| 275 | * <li><strong> visible : Boolean</strong> - Sets the <code>ContentDisplay</code>'s <code>visible</code> property.</li> | ||
| 276 | * <li><strong> blendMode : String</strong> - Sets the <code>ContentDisplay</code>'s <code>blendMode</code> property.</li> | ||
| 277 | * <li><strong> bgColor : uint </strong> - When a <code>width</code> and <code>height</code> are defined, a rectangle will be drawn inside the <code>ContentDisplay</code> immediately in order to ease the development process. It is transparent by default, but you may define a <code>bgAlpha</code> if you prefer.</li> | ||
| 278 | * <li><strong> bgAlpha : Number </strong> - Controls the alpha of the rectangle that is drawn when a <code>width</code> and <code>height</code> are defined.</li> | ||
| 279 | * <li><strong> volume : Number</strong> - A value between 0 and 1 indicating the volume at which the video should play (default is 1).</li> | ||
| 280 | * <li><strong> repeat : int</strong> - Number of times that the video should repeat. To repeat indefinitely, use -1. Default is 0.</li> | ||
| 281 | * <li><strong> checkPolicyFile : Boolean</strong> - If <code>true</code>, the VideoLoader will check for a crossdomain.xml file on the remote host (only useful when loading videos from other domains - see Adobe's docs for details about NetStream's <code>checkPolicyFile</code> property). </li> | ||
| 282 | * <li><strong> estimatedDuration : Number</strong> - Estimated duration of the video in seconds. VideoLoader will only use this value until it receives the necessary metaData from the video in order to accurately determine the video's duration. You do not need to specify an <code>estimatedDuration</code>, but doing so can help make the playProgress and some other values more accurate (until the metaData has loaded). It can also make the <code>progress/bytesLoaded/bytesTotal</code> more accurate when a <code>estimatedDuration</code> is defined, particularly in <code>bufferMode</code>.</li> | ||
| 283 | * <li><strong> deblocking : int</strong> - Indicates the type of filter applied to decoded video as part of post-processing. The default value is 0, which lets the video compressor apply a deblocking filter as needed. See Adobe's <code>flash.media.Video</code> class docs for details.</li> | ||
| 284 | * <li><strong> bufferMode : Boolean </strong> - When <code>true</code>, the loader will report its progress only in terms of the video's buffer which can be very convenient if, for example, you want to display loading progress for the video's buffer or tuck it into a LoaderMax with other loaders and allow the LoaderMax to dispatch its <code>COMPLETE</code> event when the buffer is full instead of waiting for the whole file to download. When <code>bufferMode</code> is <code>true</code>, the VideoLoader will dispatch its <code>COMPLETE</code> event when the buffer is full as opposed to waiting for the entire video to load. You can toggle the <code>bufferMode</code> anytime. Please read the full <code>bufferMode</code> property ASDoc description below for details about how it affects things like <code>bytesTotal</code>.</li> | ||
| 285 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 286 | * <li><strong> noCache : Boolean</strong> - If <code>noCache</code> is <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>getLoader()</code> or <code>getContent()</code> by url and when you're running locally)</li> | ||
| 287 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader will be inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details).</li> | ||
| 288 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this VideoLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:VideoLoader = new VideoLoader("myScript.php", {name:"textData", requireWithRoot:this.root});</code></li> | ||
| 289 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 290 | * | ||
| 291 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 292 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 293 | * <li><strong> onInit : Function</strong> - A handler function for <code>Event.INIT</code> events which will be called when the video's metaData has been received and the video is placed into the <code>ContentDisplay</code>. Make sure your onInit function accepts a single parameter of type <code>Event</code> (flash.events.Event).</li> | ||
| 294 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 295 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 296 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 297 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 298 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 299 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 300 | * </ul> | ||
| 301 | * @see com.greensock.loading.data.VideoLoaderVars | ||
| 302 | */ | ||
| 303 | public function VideoLoader(urlOrRequest:*, vars:Object=null) { | ||
| 304 | super(urlOrRequest, vars); | ||
| 305 | _type = "VideoLoader"; | ||
| 306 | _nc = new NetConnection(); | ||
| 307 | _nc.connect(null); | ||
| 308 | _nc.addEventListener("asyncError", _failHandler, false, 0, true); | ||
| 309 | _nc.addEventListener("securityError", _failHandler, false, 0, true); | ||
| 310 | |||
| 311 | _video = _content = new Video(320, 160); | ||
| 312 | _video.smoothing = Boolean(this.vars.smoothing != false); | ||
| 313 | _video.deblocking = uint(this.vars.deblocking); | ||
| 314 | |||
| 315 | _refreshNetStream(); | ||
| 316 | |||
| 317 | _duration = isNaN(this.vars.estimatedDuration) ? 200 : Number(this.vars.estimatedDuration); //just set it to a high number so that the progress starts out low. | ||
| 318 | _bufferMode = _preferEstimatedBytesInAudit = Boolean(this.vars.bufferMode == true); | ||
| 319 | _videoPaused = _pauseOnBufferFull = Boolean(this.vars.autoPlay == false); | ||
| 320 | |||
| 321 | this.volume = ("volume" in this.vars) ? Number(this.vars.volume) : 1; | ||
| 322 | |||
| 323 | if (LoaderMax.contentDisplayClass is Class) { | ||
| 324 | _sprite = new LoaderMax.contentDisplayClass(this); | ||
| 325 | if (!_sprite.hasOwnProperty("rawContent")) { | ||
| 326 | throw new Error("LoaderMax.contentDisplayClass must be set to a class with a 'rawContent' property, like com.greensock.loading.display.ContentDisplay"); | ||
| 327 | } | ||
| 328 | } else { | ||
| 329 | _sprite = new ContentDisplay(this); | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | /** @private **/ | ||
| 334 | protected function _refreshNetStream():void { | ||
| 335 | if (_ns != null) { | ||
| 336 | _ns.pause(); | ||
| 337 | try { | ||
| 338 | _ns.close(); | ||
| 339 | } catch (error:Error) { | ||
| 340 | |||
| 341 | } | ||
| 342 | _sprite.removeEventListener(Event.ENTER_FRAME, _playProgressHandler); | ||
| 343 | _ns.client = {}; | ||
| 344 | _ns.removeEventListener(NetStatusEvent.NET_STATUS, _statusHandler); | ||
| 345 | _ns.removeEventListener("ioError", _failHandler); | ||
| 346 | _ns.removeEventListener("asyncError", _failHandler); | ||
| 347 | } | ||
| 348 | |||
| 349 | _ns = (this.vars.netStream is NetStream) ? this.vars.netStream : new NetStream(_nc); | ||
| 350 | _ns.checkPolicyFile = Boolean(this.vars.checkPolicyFile == true); | ||
| 351 | _ns.client = {onMetaData:_metaDataHandler, onCuePoint:_cuePointHandler}; | ||
| 352 | |||
| 353 | _ns.addEventListener(NetStatusEvent.NET_STATUS, _statusHandler, false, 0, true); | ||
| 354 | _ns.addEventListener("ioError", _failHandler, false, 0, true); | ||
| 355 | _ns.addEventListener("asyncError", _failHandler, false, 0, true); | ||
| 356 | |||
| 357 | _ns.bufferTime = isNaN(this.vars.bufferTime) ? 5 : Number(this.vars.bufferTime); | ||
| 358 | |||
| 359 | _video.attachNetStream(_ns); | ||
| 360 | _sound = _ns.soundTransform; | ||
| 361 | } | ||
| 362 | |||
| 363 | /** @private **/ | ||
| 364 | override protected function _load():void { | ||
| 365 | _prepRequest(); | ||
| 366 | _repeatCount = 0; | ||
| 367 | _bufferFull = false; | ||
| 368 | this.metaData = null; | ||
| 369 | _pauseOnBufferFull = _videoPaused; | ||
| 370 | if (_videoPaused) { | ||
| 371 | _sound.volume = 0; | ||
| 372 | _ns.soundTransform = _sound; //temporarily silence the audio because in some cases, the Flash Player will begin playing it for a brief second right before the buffer is full (we can't pause until then) | ||
| 373 | } else { | ||
| 374 | this.volume = _volume; //ensures the volume is back to normal in case it had been temporarily silenced while buffering | ||
| 375 | } | ||
| 376 | _sprite.addEventListener(Event.ENTER_FRAME, _enterFrameHandler); | ||
| 377 | _videoComplete = _initted = false; | ||
| 378 | _ns.play(_request.url); | ||
| 379 | } | ||
| 380 | |||
| 381 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 382 | override protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 383 | _sprite.removeEventListener(Event.ENTER_FRAME, _enterFrameHandler); | ||
| 384 | _sprite.removeEventListener(Event.ENTER_FRAME, _forceTimeHandler); | ||
| 385 | _forceTime = NaN; | ||
| 386 | _initted = false; | ||
| 387 | this.metaData = null; | ||
| 388 | if (scrubLevel != 2) { | ||
| 389 | _refreshNetStream(); | ||
| 390 | (_sprite as Object).rawContent = null; | ||
| 391 | if (_video.parent != null) { | ||
| 392 | _video.parent.removeChild(_video); | ||
| 393 | } | ||
| 394 | } | ||
| 395 | |||
| 396 | if (scrubLevel >= 2) { | ||
| 397 | |||
| 398 | if (scrubLevel == 3) { | ||
| 399 | _video.attachNetStream(null); | ||
| 400 | (_sprite as Object).dispose(false, false); | ||
| 401 | } | ||
| 402 | |||
| 403 | _nc.removeEventListener("asyncError", _failHandler); | ||
| 404 | _nc.removeEventListener("securityError", _failHandler); | ||
| 405 | _ns.removeEventListener(NetStatusEvent.NET_STATUS, _statusHandler); | ||
| 406 | _ns.removeEventListener("ioError", _failHandler); | ||
| 407 | _ns.removeEventListener("asyncError", _failHandler); | ||
| 408 | |||
| 409 | (_sprite as Object).gcProtect = (scrubLevel == 3) ? null : _ns; //we need to reference the NetStream in the ContentDisplay before forcing garbage collection, otherwise gc kills the NetStream even if it's attached to the Video and is playing on the stage! | ||
| 410 | _ns.client = {}; | ||
| 411 | _video = null; | ||
| 412 | _ns = null; | ||
| 413 | _nc = null; | ||
| 414 | _sound = null; | ||
| 415 | (_sprite as Object).loader = null; | ||
| 416 | _sprite = null; | ||
| 417 | } | ||
| 418 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 419 | } | ||
| 420 | |||
| 421 | /** @private Set inside ContentDisplay's or FlexContentDisplay's "loader" setter. **/ | ||
| 422 | public function setContentDisplay(contentDisplay:Sprite):void { | ||
| 423 | _sprite = contentDisplay; | ||
| 424 | } | ||
| 425 | |||
| 426 | /** @inheritDoc **/ | ||
| 427 | override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void { | ||
| 428 | if (type == PLAY_PROGRESS) { | ||
| 429 | _dispatchPlayProgress = true; | ||
| 430 | } | ||
| 431 | super.addEventListener(type, listener, useCapture, priority, useWeakReference); | ||
| 432 | } | ||
| 433 | |||
| 434 | /** @private **/ | ||
| 435 | protected function _onBufferFull():void { | ||
| 436 | if (_pauseOnBufferFull) { | ||
| 437 | if (this.metaData == null && getTimer() - _time < 10000) { | ||
| 438 | _video.attachNetStream(null); //in some rare circumstances, the NetStream will finish buffering even before the metaData has been received. If we pause() the NetStream before the metaData arrives, it will prevent the metaData from ever arriving (bug in Flash) even after you resume(). So in this case, we allow the NetStream to continue playing so that metaData can be received, but we detach it from the Video object so that the user doesn't see the video playing. The volume is also muted, so to the user things look paused even though the NetStream is continuing to play/load. We'll re-attach the NetStream to the Video after either the metaData arrives or 10 seconds elapse. | ||
| 439 | return; | ||
| 440 | } else { | ||
| 441 | _pauseOnBufferFull = false; | ||
| 442 | this.volume = _volume; //Just resets the volume to where it should be because we temporarily made it silent during the buffer. | ||
| 443 | gotoVideoTime(0, false); | ||
| 444 | _ns.pause(); //don't just do this.videoPaused = true because sometimes Flash fires NetStream.Play.Start BEFORE the buffer is full, and we must check inside the videoPaused setter to see if if the buffer is full and wait to pause until it is. | ||
| 445 | _video.attachNetStream(_ns); | ||
| 446 | } | ||
| 447 | } | ||
| 448 | if (!_bufferFull) { | ||
| 449 | _bufferFull = true; | ||
| 450 | dispatchEvent(new LoaderEvent(VIDEO_BUFFER_FULL, this)); | ||
| 451 | } | ||
| 452 | } | ||
| 453 | |||
| 454 | /** @private **/ | ||
| 455 | override protected function _calculateProgress():void { | ||
| 456 | _cachedBytesLoaded = _ns.bytesLoaded; | ||
| 457 | if (_cachedBytesLoaded > 1) { | ||
| 458 | if (_bufferMode) { | ||
| 459 | _cachedBytesTotal = _ns.bytesTotal * (_ns.bufferTime / _duration); | ||
| 460 | if (_ns.bufferLength > 0) { | ||
| 461 | _cachedBytesLoaded = (_ns.bufferLength / _ns.bufferTime) * _cachedBytesTotal; | ||
| 462 | } | ||
| 463 | if (_cachedBytesTotal <= _cachedBytesLoaded) { | ||
| 464 | _cachedBytesTotal = (this.metaData == null) ? int(1.01 * _cachedBytesLoaded) + 1 : _cachedBytesLoaded; | ||
| 465 | } | ||
| 466 | |||
| 467 | } else { | ||
| 468 | _cachedBytesTotal = _ns.bytesTotal; | ||
| 469 | } | ||
| 470 | _auditedSize = true; | ||
| 471 | } | ||
| 472 | _cacheIsDirty = false; | ||
| 473 | } | ||
| 474 | |||
| 475 | /** | ||
| 476 | * Pauses playback of the video. | ||
| 477 | * | ||
| 478 | * @param event An optional Event which simply makes it easier to use the method as a handler for mouse clicks or other events. | ||
| 479 | * | ||
| 480 | * @see #videoPaused | ||
| 481 | * @see #gotoVideoTime() | ||
| 482 | * @see #playVideo() | ||
| 483 | * @see #videoTime | ||
| 484 | * @see #playProgress | ||
| 485 | **/ | ||
| 486 | public function pauseVideo(event:Event=null):void { | ||
| 487 | this.videoPaused = true; | ||
| 488 | } | ||
| 489 | |||
| 490 | /** | ||
| 491 | * Plays the video (if the buffer isn't full yet, playback will wait until the buffer is full). | ||
| 492 | * | ||
| 493 | * @param event An optional Event which simply makes it easier to use the method as a handler for mouse clicks or other events. | ||
| 494 | * | ||
| 495 | * @see #videoPaused | ||
| 496 | * @see #pauseVideo() | ||
| 497 | * @see #gotoVideoTime() | ||
| 498 | * @see #videoTime | ||
| 499 | * @see #playProgress | ||
| 500 | **/ | ||
| 501 | public function playVideo(event:Event=null):void { | ||
| 502 | this.videoPaused = false; | ||
| 503 | } | ||
| 504 | |||
| 505 | /** | ||
| 506 | * Attempts to jump to a certain time in the video. If the video hasn't downloaded enough to get to | ||
| 507 | * the new time or if there is no keyframe at that time value, it will get as close as possible. | ||
| 508 | * For example, to jump to exactly 3-seconds into the video and play from there:<br /><br /><code> | ||
| 509 | * | ||
| 510 | * loader.gotoVideoTime(3, true);<br /><br /></code> | ||
| 511 | * | ||
| 512 | * @param time The time (in seconds, offset from the very beginning) at which to place the virtual playhead on the video. | ||
| 513 | * @param forcePlay If <code>true</code>, the video will resume playback immediately after seeking to the new position. | ||
| 514 | * @see #pauseVideo() | ||
| 515 | * @see #playVideo() | ||
| 516 | * @see #videoTime | ||
| 517 | * @see #playProgress | ||
| 518 | **/ | ||
| 519 | public function gotoVideoTime(time:Number, forcePlay:Boolean=false):void { | ||
| 520 | if (time > _duration) { | ||
| 521 | time = _duration; | ||
| 522 | } | ||
| 523 | _ns.seek(time); | ||
| 524 | _videoComplete = false; | ||
| 525 | _forceTime = time; | ||
| 526 | _sprite.addEventListener(Event.ENTER_FRAME, _forceTimeHandler, false, 0, true); //If for example, after a video has finished playing, we seek(0) the video and immediately check the playProgress, it returns 1 instead of 0 because it takes a short time to render the first frame and accurately reflect the _ns.time variable. So we use a single ENTER_FRAME to help us override the _ns.time value briefly. | ||
| 527 | if (forcePlay) { | ||
| 528 | playVideo(); | ||
| 529 | } | ||
| 530 | } | ||
| 531 | |||
| 532 | |||
| 533 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 534 | |||
| 535 | /** @private **/ | ||
| 536 | protected function _metaDataHandler(info:Object):void { | ||
| 537 | this.metaData = info; | ||
| 538 | _duration = info.duration; | ||
| 539 | if (_ns.bufferTime > _duration) { | ||
| 540 | _ns.bufferTime = _duration; | ||
| 541 | } | ||
| 542 | if ("width" in info) { | ||
| 543 | _video.scaleX = info.width / 320; | ||
| 544 | _video.scaleY = info.height / 160; //MUST use 160 as the base width and adjust the scale because of the way Flash reports width/height/scaleX/scaleY on Video objects (it can cause problems when using the scrollRect otherwise) | ||
| 545 | } | ||
| 546 | |||
| 547 | if (!_bufferFull && _ns.bufferLength >= _ns.bufferTime) { | ||
| 548 | _onBufferFull(); | ||
| 549 | } | ||
| 550 | |||
| 551 | if (_pauseOnBufferFull) { | ||
| 552 | _video.attachNetStream(_ns); //if the NetStream isn't attached, then the Video object isn't resized properly in the ContentDisplay object. | ||
| 553 | (_sprite as Object).rawContent = _video; //resizes it appropriately | ||
| 554 | _video.attachNetStream(null); | ||
| 555 | } else { | ||
| 556 | (_sprite as Object).rawContent = _video; //resizes it appropriately | ||
| 557 | } | ||
| 558 | _initted = true; | ||
| 559 | dispatchEvent(new LoaderEvent(LoaderEvent.INIT, this, "", info)); | ||
| 560 | } | ||
| 561 | |||
| 562 | /** @private **/ | ||
| 563 | protected function _cuePointHandler(info:Object):void { | ||
| 564 | dispatchEvent(new LoaderEvent(VIDEO_CUE_POINT, this, "", info)); | ||
| 565 | } | ||
| 566 | |||
| 567 | /** @private **/ | ||
| 568 | protected function _playProgressHandler(event:Event):void { | ||
| 569 | if (_dispatchPlayProgress) { | ||
| 570 | dispatchEvent(new LoaderEvent(PLAY_PROGRESS, this)); | ||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | /** @private **/ | ||
| 575 | protected function _statusHandler(event:NetStatusEvent):void { | ||
| 576 | var code:String = event.info.code; | ||
| 577 | if (code == "NetStream.Play.Start") { | ||
| 578 | var prevPauseOnBufferFull:Boolean = _pauseOnBufferFull; | ||
| 579 | _onBufferFull(); //Flash sometimes triggers play even before the buffer is completely full, but it wouldn't make sense to report it as such. | ||
| 580 | if (!prevPauseOnBufferFull) { | ||
| 581 | _sprite.addEventListener(Event.ENTER_FRAME, _playProgressHandler); | ||
| 582 | dispatchEvent(new LoaderEvent(VIDEO_PLAY, this)); | ||
| 583 | } | ||
| 584 | } | ||
| 585 | dispatchEvent(new LoaderEvent(NetStatusEvent.NET_STATUS, this, code, event.info)); | ||
| 586 | if (code == "NetStream.Play.Stop") { | ||
| 587 | if (this.vars.repeat == -1 || uint(this.vars.repeat) > _repeatCount) { | ||
| 588 | _repeatCount++; | ||
| 589 | dispatchEvent(new LoaderEvent(VIDEO_COMPLETE, this)); | ||
| 590 | gotoVideoTime(0, true); | ||
| 591 | } else { | ||
| 592 | _videoComplete = true; | ||
| 593 | this.videoPaused = true; | ||
| 594 | _playProgressHandler(null); | ||
| 595 | dispatchEvent(new LoaderEvent(VIDEO_COMPLETE, this)); | ||
| 596 | } | ||
| 597 | } else if (code == "NetStream.Buffer.Full") { | ||
| 598 | _onBufferFull(); | ||
| 599 | } else if (code == "NetStream.Buffer.Empty") { | ||
| 600 | _bufferFull = false; | ||
| 601 | dispatchEvent(new LoaderEvent(VIDEO_BUFFER_EMPTY, this)); | ||
| 602 | } else if (code == "NetStream.Play.StreamNotFound" || | ||
| 603 | code == "NetConnection.Connect.Failed" || | ||
| 604 | code == "NetStream.Play.Failed" || | ||
| 605 | code == "NetStream.Play.FileStructureInvalid" || | ||
| 606 | code == "The MP4 doesn't contain any supported tracks") { | ||
| 607 | _failHandler(new LoaderEvent(LoaderEvent.ERROR, this, code)); | ||
| 608 | } | ||
| 609 | } | ||
| 610 | |||
| 611 | /** @private **/ | ||
| 612 | protected function _enterFrameHandler(event:Event):void { | ||
| 613 | var bl:uint = _cachedBytesLoaded; | ||
| 614 | var bt:uint = _cachedBytesTotal; | ||
| 615 | _calculateProgress(); | ||
| 616 | if (!_bufferFull && _ns.bufferLength >= _ns.bufferTime) { | ||
| 617 | _onBufferFull(); | ||
| 618 | } | ||
| 619 | if (_cachedBytesLoaded == _cachedBytesTotal && _ns.bytesTotal > 5 && (this.metaData != null || getTimer() - _time >= 10000)) { //make sure the metaData has been received because if the NetStream file is cached locally sometimes the bytesLoaded == bytesTotal BEFORE the metaData arrives. Or timeout after 10 seconds. | ||
| 620 | _sprite.removeEventListener(Event.ENTER_FRAME, _enterFrameHandler); | ||
| 621 | if (!_bufferFull) { | ||
| 622 | _onBufferFull(); | ||
| 623 | } | ||
| 624 | if (!_initted) { | ||
| 625 | (_sprite as Object).rawContent = _video; //resizes it appropriately | ||
| 626 | } | ||
| 627 | _completeHandler(event); | ||
| 628 | } else if (_dispatchProgress && (_cachedBytesLoaded / _cachedBytesTotal) != (bl / bt)) { | ||
| 629 | dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this)); | ||
| 630 | } | ||
| 631 | } | ||
| 632 | |||
| 633 | /** @private **/ | ||
| 634 | override protected function _auditStreamHandler(event:Event):void { | ||
| 635 | if (event is ProgressEvent && _bufferMode) { | ||
| 636 | (event as ProgressEvent).bytesTotal *= (_ns.bufferTime / _duration); | ||
| 637 | } | ||
| 638 | super._auditStreamHandler(event); | ||
| 639 | } | ||
| 640 | |||
| 641 | /** @private **/ | ||
| 642 | protected function _forceTimeHandler(event:Event):void { | ||
| 643 | _forceTime = NaN; | ||
| 644 | event.target.removeEventListener(Event.ENTER_FRAME, _forceTimeHandler); | ||
| 645 | } | ||
| 646 | |||
| 647 | |||
| 648 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 649 | |||
| 650 | /** A ContentDisplay (a Sprite) that contains a Video object to which the NetStream is attached. This ContentDisplay Sprite can be accessed immediately; you do not need to wait for the video to load. **/ | ||
| 651 | override public function get content():* { | ||
| 652 | return _sprite; | ||
| 653 | } | ||
| 654 | |||
| 655 | /** The <code>Video</code> object to which the NetStream was attached (automatically created by VideoLoader internally) **/ | ||
| 656 | public function get rawContent():Video { | ||
| 657 | return _content as Video; | ||
| 658 | } | ||
| 659 | |||
| 660 | /** The <code>NetStream</code> object used to load the video **/ | ||
| 661 | public function get netStream():NetStream { | ||
| 662 | return _ns; | ||
| 663 | } | ||
| 664 | |||
| 665 | /** The playback status of the video: <code>true</code> if the video's playback is paused, <code>false</code> if it isn't. **/ | ||
| 666 | public function get videoPaused():Boolean { | ||
| 667 | return _videoPaused; | ||
| 668 | } | ||
| 669 | public function set videoPaused(value:Boolean):void { | ||
| 670 | var changed:Boolean = Boolean(value != _videoPaused); | ||
| 671 | _videoPaused = value; | ||
| 672 | if (_videoPaused) { | ||
| 673 | //If we're trying to pause a NetStream that hasn't even been buffered yet, we run into problems where it won't load. So we need to set the _pauseOnBufferFull to true and then when it's buffered, it'll pause it at the beginning. | ||
| 674 | if (this.bufferProgress < 1 && this.playProgress == 0) { | ||
| 675 | _pauseOnBufferFull = true; | ||
| 676 | _sound.volume = 0; //temporarily make it silent while buffering. | ||
| 677 | _ns.soundTransform = _sound; | ||
| 678 | } else { | ||
| 679 | _pauseOnBufferFull = false; | ||
| 680 | this.volume = _volume; //Just resets the volume to where it should be in case we temporarily made it silent during the buffer. | ||
| 681 | _ns.pause(); | ||
| 682 | } | ||
| 683 | if (changed) { | ||
| 684 | _sprite.removeEventListener(Event.ENTER_FRAME, _playProgressHandler); | ||
| 685 | dispatchEvent(new LoaderEvent(VIDEO_PAUSE, this)); | ||
| 686 | } | ||
| 687 | } else { | ||
| 688 | if (_pauseOnBufferFull) { | ||
| 689 | _ns.seek(_ns.time); //if we don't seek() first, sometimes the NetStream doesn't attach to the video properly! | ||
| 690 | _video.attachNetStream(_ns); //in case we had to detach it while buffering and waiting for the metaData | ||
| 691 | _pauseOnBufferFull = false; | ||
| 692 | } | ||
| 693 | this.volume = _volume; //Just resets the volume to where it should be in case we temporarily made it silent during the buffer. | ||
| 694 | _ns.resume(); | ||
| 695 | if (changed) { | ||
| 696 | _sprite.addEventListener(Event.ENTER_FRAME, _playProgressHandler); | ||
| 697 | dispatchEvent(new LoaderEvent(VIDEO_PLAY, this)); | ||
| 698 | } | ||
| 699 | } | ||
| 700 | } | ||
| 701 | |||
| 702 | /** A value between 0 and 1 describing the progress of the buffer (0 = not buffered at all, 0.5 = halfway buffered, and 1 = fully buffered). The buffer progress is in relation to the <code>bufferTime</code> which is 5 seconds by default or you can pass a custom value in through the <code>vars</code> parameter in the constructor like <code>{bufferTime:20}</code>. **/ | ||
| 703 | public function get bufferProgress():Number { | ||
| 704 | if (uint(_ns.bytesTotal) < 5) { | ||
| 705 | return 0; | ||
| 706 | } | ||
| 707 | var prog:Number = (_ns.bufferLength / _ns.bufferTime); | ||
| 708 | return (prog > 1) ? 1 : prog; | ||
| 709 | } | ||
| 710 | |||
| 711 | /** A value between 0 and 1 describing the playback progress where 0 means the virtual playhead is at the very beginning of the video, 0.5 means it is at the halfway point and 1 means it is at the end of the video. **/ | ||
| 712 | public function get playProgress():Number { | ||
| 713 | //Often times the duration MetaData that gets passed in doesn't exactly reflect the duration, so after the FLV is finished playing, the time and duration wouldn't equal each other, so we'd get percentPlayed values of 99.26978. We have to use this _videoComplete variable to accurately reflect the status. | ||
| 714 | //If for example, after an FLV has finished playing, we gotoVideoTime(0) the FLV and immediately check the playProgress, it returns 1 instead of 0 because it takes a short time to render the first frame and accurately reflect the _ns.time variable. So we use an interval to help us override the _ns.time value briefly. | ||
| 715 | return (_videoComplete) ? 1 : (this.videoTime / _duration); | ||
| 716 | } | ||
| 717 | public function set playProgress(value:Number):void { | ||
| 718 | if (_duration != 0) { | ||
| 719 | gotoVideoTime((value * _duration), !_videoPaused); | ||
| 720 | } | ||
| 721 | } | ||
| 722 | |||
| 723 | /** The volume of the video (a value between 0 and 1). **/ | ||
| 724 | public function get volume():Number { | ||
| 725 | return _volume; | ||
| 726 | } | ||
| 727 | public function set volume(value:Number):void { | ||
| 728 | _sound.volume = _volume = value; | ||
| 729 | _ns.soundTransform = _sound; | ||
| 730 | } | ||
| 731 | |||
| 732 | /** The time (in seconds) at which the virtual playhead is positioned on the video. For example, if the virtual playhead is currently at the 3-second position (3 seconds from the beginning), this value would be 3. **/ | ||
| 733 | public function get videoTime():Number { | ||
| 734 | if (_videoComplete) { | ||
| 735 | return _duration; | ||
| 736 | } else if (_ns.time > _duration) { | ||
| 737 | return _duration * 0.995; //sometimes the NetStream reports a time that's greater than the duration so we must correct for that. | ||
| 738 | } else if (isNaN(_forceTime)) { | ||
| 739 | return _ns.time; | ||
| 740 | } else { | ||
| 741 | return _forceTime; | ||
| 742 | } | ||
| 743 | } | ||
| 744 | public function set videoTime(value:Number):void { | ||
| 745 | gotoVideoTime(value, !_videoPaused); | ||
| 746 | } | ||
| 747 | |||
| 748 | /** The duration (in seconds) of the video. This value is only accurate AFTER the metaData has been received and the <code>INIT</code> event has been dispatched. **/ | ||
| 749 | public function get duration():Number { | ||
| 750 | return _duration; | ||
| 751 | } | ||
| 752 | |||
| 753 | /** | ||
| 754 | * When <code>bufferMode</code> is <code>true</code>, the loader will report its progress only in terms of the | ||
| 755 | * video's buffer instead of its overall file loading progress which has the following effects: | ||
| 756 | * <ul> | ||
| 757 | * <li>The <code>bytesTotal</code> will be calculated based on the NetStream's <code>duration</code>, <code>bufferLength</code>, and <code>bufferTime</code> meaning it may fluctuate in order to accurately reflect the overall <code>progress</code> ratio.</li> | ||
| 758 | * <li>Its <code>COMPLETE</code> event will be dispatched as soon as the buffer is full, so if the VideoLoader is nested in a LoaderMax, the LoaderMax will move on to the next loader in its queue at that point. However, the VideoLoader's NetStream will continue to load in the background, using up bandwidth.</li> | ||
| 759 | * </ul> | ||
| 760 | * | ||
| 761 | * This can be very convenient if, for example, you want to display loading progress based on the video's buffer | ||
| 762 | * or if you want to load a series of loaders in a LoaderMax and have it fire its <code>COMPLETE</code> event | ||
| 763 | * when the buffer is full (as opposed to waiting for the entire video to load). | ||
| 764 | **/ | ||
| 765 | public function get bufferMode():Boolean { | ||
| 766 | return _bufferMode; | ||
| 767 | } | ||
| 768 | public function set bufferMode(value:Boolean):void { | ||
| 769 | _bufferMode = value; | ||
| 770 | _preferEstimatedBytesInAudit = _bufferMode; | ||
| 771 | _calculateProgress(); | ||
| 772 | } | ||
| 773 | |||
| 774 | } | ||
| 775 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.3 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading { | ||
| 8 | import com.greensock.events.LoaderEvent; | ||
| 9 | import com.greensock.loading.DataLoader; | ||
| 10 | import com.greensock.loading.core.LoaderCore; | ||
| 11 | |||
| 12 | import flash.events.ErrorEvent; | ||
| 13 | import flash.events.Event; | ||
| 14 | import flash.events.ProgressEvent; | ||
| 15 | import flash.net.URLLoader; | ||
| 16 | import flash.system.ApplicationDomain; | ||
| 17 | import flash.system.LoaderContext; | ||
| 18 | import flash.system.SecurityDomain; | ||
| 19 | |||
| 20 | /** Dispatched when any loader that the XMLLoader discovered in the XML dispatches an OPEN event. **/ | ||
| 21 | [Event(name="childOpen", type="com.greensock.events.LoaderEvent")] | ||
| 22 | /** Dispatched when any loader that the XMLLoader discovered in the XML dispatches a PROGRESS event. **/ | ||
| 23 | [Event(name="childProgress", type="com.greensock.events.LoaderEvent")] | ||
| 24 | /** Dispatched when any loader that the XMLLoader discovered in the XML dispatches a COMPLETE event. **/ | ||
| 25 | [Event(name="childComplete", type="com.greensock.events.LoaderEvent")] | ||
| 26 | /** Dispatched when any loader that the XMLLoader discovered in the XML dispatches a FAIL event. **/ | ||
| 27 | [Event(name="childFail", type="com.greensock.events.LoaderEvent")] | ||
| 28 | /** Dispatched when any loader that the XMLLoader discovered in the XML dispatches a CANCEL event. **/ | ||
| 29 | [Event(name="childCancel", type="com.greensock.events.LoaderEvent")] | ||
| 30 | /** Dispatched when any loader that the XMLLoader discovered in the XML dispatches a SCRIPT_ACCESS_DENIED event. **/ | ||
| 31 | [Event(name="scriptAccessDenied", type="com.greensock.events.LoaderEvent")] | ||
| 32 | /** Dispatched when the loader's <code>httpStatus</code> value changes. **/ | ||
| 33 | [Event(name="httpStatus", type="com.greensock.events.LoaderEvent")] | ||
| 34 | /** Dispatched when the loader experiences a SECURITY_ERROR which can occur when the XML file is loaded from another domain and there is no crossdomain.xml file in place granting appropriate access. **/ | ||
| 35 | [Event(name="securityError", type="com.greensock.events.LoaderEvent")] | ||
| 36 | /** | ||
| 37 | * Loads an XML file and automatically searches it for LoaderMax-related nodes like <code><LoaderMax>, | ||
| 38 | * <ImageLoader>, <SWFLoader>, <XMLLoader>, <DataLoader> <CSSLoader>, <MP3Loader></code>, | ||
| 39 | * etc.; if it finds any, it will create the necessary instances and begin loading them if they have a <code>load="true"</code> | ||
| 40 | * attribute. The XMLLoader's <code>progress</code> will automatically factor in the dynamically-created | ||
| 41 | * loaders that have the <code>load="true"</code> attribute and it won't dispatch its <code>COMPLETE</code> event | ||
| 42 | * until those loaders have completed as well (unless <code>integrateProgress:false</code> is passed to the constructor). | ||
| 43 | * For example, let's say the XML file contains the following XML: | ||
| 44 | * | ||
| 45 | * @example Example XML code:<listing version="3.0"> | ||
| 46 | <?xml version="1.0" encoding="iso-8859-1"?> | ||
| 47 | <data> | ||
| 48 | <widget name="myWidget1" id="10"> | ||
| 49 | <ImageLoader name="widget1" url="img/widget1.jpg" estimatedBytes="2000" /> | ||
| 50 | </widget> | ||
| 51 | <widget name="myWidget2" id="23"> | ||
| 52 | <ImageLoader name="widget2" url="img/widget2.jpg" estimatedBytes="2800" load="true" /> | ||
| 53 | </widget> | ||
| 54 | <LoaderMax name="dynamicLoaderMax" load="true" prependURLs="http://www.greensock.com/"> | ||
| 55 | <ImageLoader name="photo1" url="img/photo1.jpg" /> | ||
| 56 | <ImageLoader name="logo" url="img/corporate_logo.png" estimatedBytes="2500" /> | ||
| 57 | <SWFLoader name="mainSWF" url="swf/main.swf" autoPlay="false" estimatedBytes="15000" /> | ||
| 58 | <MP3Loader name="audio" url="mp3/intro.mp3" autoPlay="true" loops="100" /> | ||
| 59 | </LoaderMax> | ||
| 60 | </data> | ||
| 61 | </listing> | ||
| 62 | * | ||
| 63 | * Once the XML has been loaded and parsed, the XMLLoader will recognize the 7 LoaderMax-related nodes | ||
| 64 | * (assuming you activated the various types of loaders - see the <code>activate()</code> method for details) | ||
| 65 | * and it will create instances dynamically. Then it will start loading the ones that had a <code>load="true"</code> | ||
| 66 | * attribute which in this case means all but the first loader will be loaded in the order they were defined in the XML. | ||
| 67 | * Notice the loaders nested inside the <code><LoaderMax></code> don't have <code>load="true"</code> but | ||
| 68 | * they will be loaded anyway because their parent LoaderMax has the <code>load="true"</code> attribute. | ||
| 69 | * After the XMLLoader's <code>INIT</code> event is dispatched, you can get any loader by name or URL with the | ||
| 70 | * <code>LoaderMax.getLoader()</code> method and monitor its progress or control it as you please. | ||
| 71 | * And after the XMLLoader's <code>COMPLETE</code> event is dispatched, you can use <code>LoaderMax.getContent()</code> | ||
| 72 | * to get content based on the name or URL of any of the loaders that had <code>load="true"</code> defined | ||
| 73 | * in the XML. For example: | ||
| 74 | * | ||
| 75 | * @example Example AS3 code:<listing version="3.0"> | ||
| 76 | var loader:XMLLoader = new XMLLoader("xml/doc.xml", {name:"xmlDoc", onComplete:completeHandler}); | ||
| 77 | |||
| 78 | function completeHandler(event:LoaderEvent):void { | ||
| 79 | |||
| 80 | //get the content from the "photo1" ImageLoader that was defined inside the XML | ||
| 81 | var photo:ContentDisplay = LoaderMax.getContent("photo1"); | ||
| 82 | |||
| 83 | //add it to the display list | ||
| 84 | addChild(photo); | ||
| 85 | |||
| 86 | //fade it in | ||
| 87 | TweenLite.from(photo, 1, {alpha:0}); | ||
| 88 | } | ||
| 89 | </listing> | ||
| 90 | * | ||
| 91 | * You do <strong>not</strong> need to put loader-related nodes in your XML files. It is a convenience that is completely | ||
| 92 | * optional. XMLLoader does a great job of loading plain XML data even without the fancy automatic parsing of | ||
| 93 | * loader data. <br /><br /> | ||
| 94 | * | ||
| 95 | * <strong>OPTIONAL VARS PROPERTIES</strong><br /> | ||
| 96 | * The following special properties can be passed into the XMLLoader constructor via its <code>vars</code> | ||
| 97 | * parameter which can be either a generic object or an <code><a href="data/XMLLoaderVars.html">XMLLoaderVars</a></code> object:<br /> | ||
| 98 | * <ul> | ||
| 99 | * <li><strong> name : String</strong> - A name that is used to identify the XMLLoader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 100 | * <li><strong> integrateProgress : Boolean</strong> - By default, the XMLLoader will automatically look for LoaderMax-related nodes like <code><LoaderMax>, <ImageLoader>, <SWFLoader>, <XMLLoader>, <MP3Loader>, <DataLoader></code>, and <code><CSSLoader></code> inside the XML when it inits. If it finds any that have a <code>load="true"</code> attribute, it will begin loading them and integrate their progress into the XMLLoader's overall progress. Its <code>COMPLETE</code> event won't fire until all of these loaders have completed as well. If you prefer NOT to integrate the dynamically-created loader instances into the XMLLoader's overall <code>progress</code>, set <code>integrateProgress</code> to <code>false</code>.</li> | ||
| 101 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 102 | * <li><strong> noCache : Boolean</strong> - If <code>noCache</code> is <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>getLoader()</code> or <code>getContent()</code> by url and when you're running locally)</li> | ||
| 103 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the XML has been loaded and analyzed enough to determine the size of any dynamic loaders that were found in the XML data (like <ImageLoader> nodes, etc.), it will adjust the <code>bytesTotal</code> accordingly. Setting <code>estimatedBytes</code> is optional, but it provides a way to avoid situations where the <code>progress</code> and <code>bytesTotal</code> values jump around as XMLLoader recognizes nested loaders in the XML and audits their size. The <code>estimatedBytes</code> value should include all nested loaders as well, so if your XML file itself is 500 bytes and you have 3 <ImageLoader> tags with <code>load="true"</code> and each image is about 2000 bytes, your XMLLoader's <code>estimatedBytes</code> should be 6500. The more accurate the value, the more accurate the loaders' overall progress will be.</li> | ||
| 104 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this XMLLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:XMLLoader = new XMLLoader("data.xml", {name:"data", requireWithRoot:this.root});</code></li> | ||
| 105 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 106 | * | ||
| 107 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 108 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 109 | * <li><strong> onInit : Function</strong> - A handler function for <code>LoaderEvent.INIT</code> events which are dispatched when the loader finishes loading the XML file, parses its contents, and creates any dynamic XML-driven loaders. If any dynamic loaders are created and have a <code>load="true"</code> attribute, they will begin loading at this point and the XMLLoader's <code>COMPLETE</code> will not be dispatched until the loaders have completed as well. Make sure your onInit function accepts a single parameter of type <code>Event</code> (flash.events.Event).</li> | ||
| 110 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 111 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 112 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 113 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 114 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 115 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 116 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 117 | * <li><strong> onSecurityError : Function</strong> - A handler function for <code>LoaderEvent.SECURITY_ERROR</code> events which onError handles as well, so you can use that as more of a catch-all whereas onSecurityError is specifically for SECURITY_ERROR events. Make sure your onSecurityError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 118 | * <li><strong> onChildOpen : Function</strong> - A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 119 | * <li><strong> onChildProgress : Function</strong> - A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML dispatches a <code>PROGRESS</code> event. To listen for changes in the XMLLoader's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the XMLLoader, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 120 | * <li><strong> onChildComplete : Function</strong> - A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 121 | * <li><strong> onChildCancel : Function</strong> - A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on any nested LoaderMax-related loaders that were defined in the XML due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 122 | * <li><strong> onChildFail : Function</strong> - A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 123 | * </ul><br /> | ||
| 124 | * | ||
| 125 | * <strong>Note:</strong> Using a <code><a href="data/XMLLoaderVars.html">XMLLoaderVars</a></code> instance | ||
| 126 | * instead of a generic object to define your <code>vars</code> is a bit more verbose but provides | ||
| 127 | * code hinting and improved debugging because it enforces strict data typing. Use whichever one you prefer.<br /><br /> | ||
| 128 | * | ||
| 129 | * XMLLoader recognizes a few additional attributes for dynamically-created loaders that are defined in the XML: | ||
| 130 | * <ul> | ||
| 131 | * <li><strong>load="true | false"</strong> - If <code>load</code> is <code>"true"</code>, the loader will be loaded by the XMLLoader and its progress will be integrated with the XMLLoader's overall progress.</li> | ||
| 132 | * <li><strong>prependURLs</strong> (<LoaderMax> nodes only) - To prepend a certain String value to the beginning of all children of a <LoaderMax>, use <code>prependURLs</code>. For example, <code><LoaderMax name="mainQueue" prependURLs="http://www.greensock.com/images/"><ImageLoader url="image1.jpg" /></LoaderMax></code> would cause the ImageLoader's url to become "http://www.greensock.com/images/image1.jpg". </li> | ||
| 133 | * <li><strong>replaceURLText</strong> (<LoaderMax> nodes only) - To replace a certain substring in all child loaders of a <LoaderMax> with another value, use <code>replaceURLText</code>. Separate the old value that should be replaced from the new one that should replace it with a comma (","). For example, <code><LoaderMax name="mainQueue" replaceURLText="{imageDirectory},http://www.greensock.com/images/"><ImageLoader url="{imageDirectory}image1.jpg" /></LoaderMax></code> would cause the ImageLoader's <code>url</code> to become "http://www.greensock.com/images/image1.jpg". </li> | ||
| 134 | * <li><strong>context="child | separate | own"</strong> - Only valid for <code><ImageLoader></code> and <code><SWFLoader></code> loaders. It defines the LoaderContext's ApplicationDomain (see Adobe's <code>LoaderContext</code> docs for details). <code>"child"</code> is the default.</li> | ||
| 135 | * </ul><br /> | ||
| 136 | * | ||
| 137 | * <code>content</code> data type: <strong><code>XML</code></strong><br /><br /> | ||
| 138 | * | ||
| 139 | * @example Example AS3 code:<listing version="3.0"> | ||
| 140 | import com.greensock.loading.~~; | ||
| 141 | import com.greensock.loading.display.~~; | ||
| 142 | import com.greensock.events.LoaderEvent; | ||
| 143 | |||
| 144 | //we know the XML contains ImageLoader, SWFLoader, DataLoader, and MP3Loader data, so we need to activate those classes once in the swf so that the XMLLoader can recognize them. | ||
| 145 | LoaderMax.activate([ImageLoader, SWFLoader, DataLoader, MP3Loader]); | ||
| 146 | |||
| 147 | //create an XMLLoader | ||
| 148 | var loader:XMLLoader = new XMLLoader("xml/doc.xml", {name:"xmlDoc", requireWithRoot:this.root, estimatedBytes:1400}); | ||
| 149 | |||
| 150 | //begin loading | ||
| 151 | loader.load(); | ||
| 152 | |||
| 153 | //Or you could put the XMLLoader into a LoaderMax. Create one first... | ||
| 154 | var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler}); | ||
| 155 | |||
| 156 | //append the XMLLoader and several other loaders | ||
| 157 | queue.append( loader ); | ||
| 158 | queue.append( new SWFLoader("swf/main.swf", {name:"mainSWF", estimatedBytes:4800}) ); | ||
| 159 | queue.append( new ImageLoader("img/photo1.jpg", {name:"photo1"}) ); | ||
| 160 | |||
| 161 | //begin loading queue | ||
| 162 | queue.load(); | ||
| 163 | |||
| 164 | function progressHandler(event:LoaderEvent):void { | ||
| 165 | trace("progress: " + event.target.progress); | ||
| 166 | } | ||
| 167 | |||
| 168 | function completeHandler(event:LoaderEvent):void { | ||
| 169 | trace("load complete. XML content: " + LoaderMax.getContent("xmlDoc")); | ||
| 170 | |||
| 171 | //Assuming there was an <ImageLoader name="image1" url="img/image1.jpg" load="true" /> node in the XML, get the associated image... | ||
| 172 | var image:ContentDisplay = LoaderMax.getContent("image1"); | ||
| 173 | addChild(image); | ||
| 174 | } | ||
| 175 | |||
| 176 | function errorHandler(event:LoaderEvent):void { | ||
| 177 | trace("error occured with " + event.target + ": " + event.text); | ||
| 178 | } | ||
| 179 | </listing> | ||
| 180 | * | ||
| 181 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 182 | * | ||
| 183 | * @see com.greensock.loading.data.XMLLoaderVars | ||
| 184 | * | ||
| 185 | * @author Jack Doyle, jack@greensock.com | ||
| 186 | */ | ||
| 187 | public class XMLLoader extends DataLoader { | ||
| 188 | /** @private **/ | ||
| 189 | private static var _classActivated:Boolean = _activateClass("XMLLoader", XMLLoader, "xml,php,jsp,asp,cfm,cfml,aspx"); | ||
| 190 | /** @private Any non-String variable types that XMLLoader should recognized in loader nodes like <ImageLoader>, <VideoLoader>, etc. **/ | ||
| 191 | protected static var _varTypes:Object = {skipFailed:true, skipPaused:true, paused:false, load:false, noCache:false, maxConnections:2, autoPlay:false, autoDispose:false, smoothing:false, estimatedBytes:1, x:1, y:1, width:1, height:1, scaleX:1, scaleY:1, rotation:1, alpha:1, visible:true, bgColor:0, bgAlpha:0, deblocking:1, repeat:1, checkPolicyFile:false, centerRegistration:false, bufferTime:5, volume:1, bufferMode:false, estimatedDuration:200, crop:false}; | ||
| 192 | /** @private contains only the parsed loaders that had the load="true" XML attribute. It also contains the _parsed LoaderMax which is paused, so it won't load (we put it in there for easy searching). **/ | ||
| 193 | protected var _loadingQueue:LoaderMax; | ||
| 194 | /** @private contains all the parsed loaders (<ImageLoader>, <SWFLoader>, <MP3Loader>, <XMLLoader>, etc.) but it is paused. Any loaders that have the load="true" XML attribute will be put into the _loadingQueue. _parsed is also put into the _loadingQueue for easy searching. **/ | ||
| 195 | protected var _parsed:LoaderMax; | ||
| 196 | /** @private **/ | ||
| 197 | protected var _initted:Boolean; | ||
| 198 | |||
| 199 | /** | ||
| 200 | * Constructor | ||
| 201 | * | ||
| 202 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content. | ||
| 203 | * @param vars An object containing optional configuration details. For example: <code>new XMLLoader("xml/data.xml", {name:"data", onComplete:completeHandler, onProgress:progressHandler})</code>.<br /><br /> | ||
| 204 | * | ||
| 205 | * The following special properties can be passed into the constructor via the <code>vars</code> parameter | ||
| 206 | * which can be either a generic object or an <code><a href="data/XMLLoaderVars.html">XMLLoaderVars</a></code> object:<br /> | ||
| 207 | * <ul> | ||
| 208 | * <li><strong> name : String</strong> - A name that is used to identify the XMLLoader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21".</li> | ||
| 209 | * <li><strong> integrateProgress : Boolean</strong> - By default, the XMLLoader will automatically look for LoaderMax-related nodes like <code><LoaderMax>, <ImageLoader>, <SWFLoader>, <XMLLoader>, <MP3Loader>, <DataLoader></code>, and <code><CSSLoader></code> inside the XML when it inits. If it finds any that have a <code>load="true"</code> attribute, it will begin loading them and integrate their progress into the XMLLoader's overall progress. Its <code>COMPLETE</code> event won't fire until all of these loaders have completed as well. If you prefer NOT to integrate the dynamically-created loader instances into the XMLLoader's overall <code>progress</code>, set <code>integrateProgress</code> to <code>false</code>.</li> | ||
| 210 | * <li><strong> alternateURL : String</strong> - If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example).</li> | ||
| 211 | * <li><strong> noCache : Boolean</strong> - If <code>noCache</code> is <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>getLoader()</code> or <code>getContent()</code> by url and when you're running locally)</li> | ||
| 212 | * <li><strong> estimatedBytes : uint</strong> - Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the XML has been loaded and analyzed enough to determine the size of any dynamic loaders that were found in the XML data (like <ImageLoader> nodes, etc.), it will adjust the <code>bytesTotal</code> accordingly. Setting <code>estimatedBytes</code> is optional, but it provides a way to avoid situations where the <code>progress</code> and <code>bytesTotal</code> values jump around as XMLLoader recognizes nested loaders in the XML and audits their size. The <code>estimatedBytes</code> value should include all nested loaders as well, so if your XML file itself is 500 bytes and you have 3 <ImageLoader> tags with <code>load="true"</code> and each image is about 2000 bytes, your XMLLoader's <code>estimatedBytes</code> should be 6500. The more accurate the value, the more accurate the loaders' overall progress will be.</li> | ||
| 213 | * <li><strong> requireWithRoot : DisplayObject</strong> - LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this XMLLoader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>var loader:XMLLoader = new XMLLoader("data.xml", {name:"data", requireWithRoot:this.root});</code></li> | ||
| 214 | * <li><strong> autoDispose : Boolean</strong> - When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. | ||
| 215 | * | ||
| 216 | * <br /><br />----EVENT HANDLER SHORTCUTS----</li> | ||
| 217 | * <li><strong> onOpen : Function</strong> - A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 218 | * <li><strong> onInit : Function</strong> - A handler function for <code>LoaderEvent.INIT</code> events which are dispatched when the loader finishes loading the XML file, parses its contents, and creates any dynamic XML-driven loaders. If any dynamic loaders are created and have a <code>load="true"</code> attribute, they will begin loading at this point and the XMLLoader's <code>COMPLETE</code> will not be dispatched until the loaders have completed as well. Make sure your onInit function accepts a single parameter of type <code>Event</code> (flash.events.Event).</li> | ||
| 219 | * <li><strong> onProgress : Function</strong> - A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.</li> | ||
| 220 | * <li><strong> onComplete : Function</strong> - A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 221 | * <li><strong> onCancel : Function</strong> - A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 222 | * <li><strong> onError : Function</strong> - A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 223 | * <li><strong> onFail : Function</strong> - A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 224 | * <li><strong> onIOError : Function</strong> - A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 225 | * <li><strong> onHTTPStatus : Function</strong> - A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).</li> | ||
| 226 | * <li><strong> onSecurityError : Function</strong> - A handler function for <code>LoaderEvent.SECURITY_ERROR</code> events which onError handles as well, so you can use that as more of a catch-all whereas onSecurityError is specifically for SECURITY_ERROR events. Make sure your onSecurityError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 227 | * <li><strong> onChildOpen : Function</strong> - A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 228 | * <li><strong> onChildProgress : Function</strong> - A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML dispatches a <code>PROGRESS</code> event. To listen for changes in the XMLLoader's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the XMLLoader, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 229 | * <li><strong> onChildComplete : Function</strong> - A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 230 | * <li><strong> onChildCancel : Function</strong> - A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on any nested LoaderMax-related loaders that were defined in the XML due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 231 | * <li><strong> onChildFail : Function</strong> - A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> | ||
| 232 | * </ul> | ||
| 233 | * @see com.greensock.loading.data.XMLLoaderVars | ||
| 234 | */ | ||
| 235 | public function XMLLoader(urlOrRequest:*, vars:Object=null) { | ||
| 236 | super(urlOrRequest, vars); | ||
| 237 | _preferEstimatedBytesInAudit = true; | ||
| 238 | _type = "XMLLoader"; | ||
| 239 | _loader.dataFormat = "text"; //just to make sure it wasn't overridden if the "format" special vars property was passed into in DataLoader's constructor. | ||
| 240 | } | ||
| 241 | |||
| 242 | /** @private **/ | ||
| 243 | override protected function _load():void { | ||
| 244 | if (!_initted) { | ||
| 245 | _prepRequest(); | ||
| 246 | _loader.load(_request); | ||
| 247 | } else if (_loadingQueue != null) { | ||
| 248 | _changeQueueListeners(true); | ||
| 249 | _loadingQueue.load(false); | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | /** @private **/ | ||
| 254 | protected function _changeQueueListeners(add:Boolean):void { | ||
| 255 | if (_loadingQueue != null) { | ||
| 256 | var p:String; | ||
| 257 | if (add && this.vars.integrateProgress != false) { | ||
| 258 | _loadingQueue.addEventListener(LoaderEvent.COMPLETE, _completeHandler, false, 0, true); | ||
| 259 | _loadingQueue.addEventListener(LoaderEvent.PROGRESS, _progressHandler, false, 0, true); | ||
| 260 | _loadingQueue.addEventListener(LoaderEvent.FAIL, _failHandler, false, 0, true); | ||
| 261 | for (p in _listenerTypes) { | ||
| 262 | if (p != "onProgress" && p != "onInit") { | ||
| 263 | _loadingQueue.addEventListener(_listenerTypes[p], _passThroughEvent, false, 0, true); | ||
| 264 | } | ||
| 265 | } | ||
| 266 | } else { | ||
| 267 | _loadingQueue.removeEventListener(LoaderEvent.COMPLETE, _completeHandler); | ||
| 268 | _loadingQueue.removeEventListener(LoaderEvent.PROGRESS, _progressHandler); | ||
| 269 | _loadingQueue.removeEventListener(LoaderEvent.FAIL, _failHandler); | ||
| 270 | for (p in _listenerTypes) { | ||
| 271 | if (p != "onProgress" && p != "onInit") { | ||
| 272 | _loadingQueue.removeEventListener(_listenerTypes[p], _passThroughEvent); | ||
| 273 | } | ||
| 274 | } | ||
| 275 | } | ||
| 276 | } | ||
| 277 | } | ||
| 278 | |||
| 279 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 280 | override protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 281 | if (_loadingQueue != null) { | ||
| 282 | _changeQueueListeners(false); | ||
| 283 | if (scrubLevel == 0) { | ||
| 284 | _loadingQueue.cancel(); | ||
| 285 | } else { | ||
| 286 | _loadingQueue.dispose(Boolean(scrubLevel == 3)); | ||
| 287 | _loadingQueue = null; | ||
| 288 | } | ||
| 289 | } | ||
| 290 | if (scrubLevel >= 1) { | ||
| 291 | if (_parsed != null) { | ||
| 292 | _parsed.dispose(Boolean(scrubLevel == 3)); | ||
| 293 | _parsed = null; | ||
| 294 | } | ||
| 295 | _initted = false; | ||
| 296 | } | ||
| 297 | _cacheIsDirty = true; | ||
| 298 | var content:* = _content; | ||
| 299 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 300 | if (scrubLevel == 0) { | ||
| 301 | _content = content; //super._dump() nulls "_content" but if the XML loaded and not the loading queue (yet), we should keep the XML content. | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 305 | /** @private **/ | ||
| 306 | override protected function _calculateProgress():void { | ||
| 307 | _cachedBytesLoaded = _loader.bytesLoaded; | ||
| 308 | _cachedBytesTotal = _loader.bytesTotal; | ||
| 309 | if (_cachedBytesTotal < _cachedBytesLoaded || _initted) { | ||
| 310 | //In Chrome when the XML file exceeds a certain size and gzip is enabled on the server, Adobe's URLLoader reports bytesTotal as 0!!! | ||
| 311 | //and in Firefox, if gzip was enabled, on very small files the URLLoader's bytesLoaded would never quite reach the bytesTotal even after the COMPLETE event fired! | ||
| 312 | _cachedBytesTotal = _cachedBytesLoaded; | ||
| 313 | } | ||
| 314 | var estimate:uint = uint(this.vars.estimatedBytes); | ||
| 315 | if (this.vars.integrateProgress == false) { | ||
| 316 | // do nothing | ||
| 317 | } else if (_loadingQueue != null && (uint(this.vars.estimatedBytes) < _cachedBytesLoaded || _loadingQueue.auditedSize)) { //make sure that estimatedBytes is prioritized until the _loadingQueue has audited its size successfully! | ||
| 318 | if (_loadingQueue.status <= LoaderStatus.COMPLETED) { | ||
| 319 | _cachedBytesLoaded += _loadingQueue.bytesLoaded; | ||
| 320 | _cachedBytesTotal += _loadingQueue.bytesTotal; | ||
| 321 | } | ||
| 322 | } else if (uint(this.vars.estimatedBytes) > _cachedBytesLoaded && (!_initted || (_loadingQueue != null && _loadingQueue.status <= LoaderStatus.COMPLETED && !_loadingQueue.auditedSize))) { | ||
| 323 | _cachedBytesTotal = uint(this.vars.estimatedBytes); | ||
| 324 | } | ||
| 325 | if (!_initted && _cachedBytesLoaded == _cachedBytesTotal) { | ||
| 326 | _cachedBytesLoaded = int(_cachedBytesLoaded * 0.99); //don't allow the progress to hit 1 yet | ||
| 327 | } | ||
| 328 | _cacheIsDirty = false; | ||
| 329 | } | ||
| 330 | |||
| 331 | /** | ||
| 332 | * Finds a particular loader inside any LoaderMax instances that were discovered in the xml content. | ||
| 333 | * For example:<br /><br /><code> | ||
| 334 | * | ||
| 335 | * var xmlLoader:XMLLoader = new XMLLoader("xml/doc.xml", {name:"xmlDoc", onComplete:completeHandler});<br /> | ||
| 336 | * function completeHandler(event:Event):void {<br /> | ||
| 337 | * var imgLoader:ImageLoader = xmlLoader.getLoader("imageInXML") as ImageLoader;<br /> | ||
| 338 | * addChild(imgLoader.content);<br /> | ||
| 339 | * }<br /><br /></code> | ||
| 340 | * | ||
| 341 | * The static <code>LoaderMax.getLoader()</code> method can be used instead which searches all loaders. | ||
| 342 | * | ||
| 343 | * @param nameOrURL The name or url associated with the loader that should be found. | ||
| 344 | * @return The loader associated with the name or url. Returns <code>null</code> if none were found. | ||
| 345 | */ | ||
| 346 | public function getLoader(nameOrURL:String):* { | ||
| 347 | return (_parsed != null) ? _parsed.getLoader(nameOrURL) : null; | ||
| 348 | } | ||
| 349 | |||
| 350 | /** | ||
| 351 | * Finds a particular loader's <code>content</code> from inside any loaders that were dynamically | ||
| 352 | * generated based on the xml data. For example:<br /><br /><code> | ||
| 353 | * | ||
| 354 | * var loader:XMLLoader = new XMLLoader("xml/doc.xml", {name:"xmlDoc", onComplete:completeHandler});<br /> | ||
| 355 | * function completeHandler(event:Event):void {<br /> | ||
| 356 | * var subloadedImage:Bitmap = loader.getContent("imageInXML");<br /> | ||
| 357 | * addChild(subloadedImage);<br /> | ||
| 358 | * }<br /><br /></code> | ||
| 359 | * | ||
| 360 | * The static <code>LoaderMax.getContent()</code> method can be used instead which searches all loaders. | ||
| 361 | * | ||
| 362 | * @param nameOrURL The name or url associated with the loader whose content should be found. | ||
| 363 | * @return The content associated with the loader's name or url. Returns <code>null</code> if none were found. | ||
| 364 | * @see #content | ||
| 365 | */ | ||
| 366 | public function getContent(nameOrURL:String):* { | ||
| 367 | if (nameOrURL == this.name || nameOrURL == _url) { | ||
| 368 | return _content; | ||
| 369 | } | ||
| 370 | var loader:LoaderCore = this.getLoader(nameOrURL); | ||
| 371 | return (loader != null) ? loader.content : null; | ||
| 372 | } | ||
| 373 | |||
| 374 | /** @private **/ | ||
| 375 | public function getChildren(includeNested:Boolean=false, omitLoaderMaxes:Boolean=false):Array { | ||
| 376 | return (_parsed != null) ? _parsed.getChildren(includeNested, omitLoaderMaxes) : []; | ||
| 377 | } | ||
| 378 | |||
| 379 | //---- STATIC METHODS ------------------------------------------------------------------------------------ | ||
| 380 | |||
| 381 | /** @private **/ | ||
| 382 | protected static function _parseVars(xml:XML):Object { | ||
| 383 | var v:Object = {}; | ||
| 384 | var s:String, type:String, value:String, domain:ApplicationDomain; | ||
| 385 | var list:XMLList = xml.attributes(); | ||
| 386 | for each (var attribute:XML in list) { | ||
| 387 | s = attribute.name(); | ||
| 388 | value = attribute.toString(); | ||
| 389 | if (s == "url") { | ||
| 390 | continue; | ||
| 391 | } else if (s == "domain") { | ||
| 392 | v.context = new LoaderContext(true, | ||
| 393 | (value == "child") ? new ApplicationDomain(ApplicationDomain.currentDomain) : (value == "separate") ? new ApplicationDomain() : ApplicationDomain.currentDomain, | ||
| 394 | SecurityDomain.currentDomain); | ||
| 395 | continue; | ||
| 396 | } | ||
| 397 | type = typeof(_varTypes[s]); | ||
| 398 | if (type == "boolean") { | ||
| 399 | v[s] = Boolean(value == "true" || value == "1"); | ||
| 400 | } else if (type == "number") { | ||
| 401 | v[s] = Number(value); | ||
| 402 | } else { | ||
| 403 | v[s] = value; | ||
| 404 | } | ||
| 405 | } | ||
| 406 | return v; | ||
| 407 | } | ||
| 408 | |||
| 409 | /** | ||
| 410 | * Parses an XML object and finds all activated loader types (like LoaderMax, ImageLoader, SWFLoader, DataLoader, | ||
| 411 | * CSSLoader, MP3Loader, etc.), creates the necessary instances, and appends them to the LoaderMax that is defined | ||
| 412 | * in the 2nd parameter. Don't forget to make sure you <code>activate()</code> the necessary loader types that you | ||
| 413 | * want XMLLoader to recognize in the XML, like:<br /><br /><code> | ||
| 414 | * | ||
| 415 | * LoaderMax.activate([ImageLoader, SWFLoader]); //or whatever types you're using.</code> | ||
| 416 | * | ||
| 417 | * @param xml The XML to parse | ||
| 418 | * @param all The LoaderMax instance to which all parsed loaders should be appended | ||
| 419 | * @param toLoad The LoaderMax instance to which <strong>ONLY</strong> parsed loaders that have a <code>load="true"</code> attribute defined in the XML should be appended. These loaders will also be appended to the LoaderMax defined in the <code>all</code> parameter. | ||
| 420 | */ | ||
| 421 | public static function parseLoaders(xml:XML, all:LoaderMax, toLoad:LoaderMax=null):void { | ||
| 422 | var loader:LoaderCore, queue:LoaderMax, curName:String, replaceText:Array, loaderClass:Class; | ||
| 423 | for each (var node:XML in xml.children()) { | ||
| 424 | curName = node.name(); | ||
| 425 | if (curName == "LoaderMax") { | ||
| 426 | queue = all.append(new LoaderMax(_parseVars(node))) as LoaderMax; | ||
| 427 | if (toLoad != null && queue.vars.load) { | ||
| 428 | toLoad.append(queue); | ||
| 429 | } | ||
| 430 | parseLoaders(node, queue, toLoad); | ||
| 431 | if ("replaceURLText" in queue.vars) { | ||
| 432 | replaceText = queue.vars.replaceURLText.split(","); | ||
| 433 | if (replaceText.length == 2) { | ||
| 434 | queue.replaceURLText(replaceText[0], replaceText[1], false); | ||
| 435 | } | ||
| 436 | } | ||
| 437 | if ("prependURLs" in queue.vars) { | ||
| 438 | queue.prependURLs(queue.vars.prependURLs, false); | ||
| 439 | } | ||
| 440 | } else { | ||
| 441 | if (curName in _types) { | ||
| 442 | loaderClass = _types[curName]; | ||
| 443 | loader = all.append(new loaderClass(node.@url, _parseVars(node))); | ||
| 444 | if (toLoad != null && loader.vars.load) { | ||
| 445 | toLoad.append(loader); | ||
| 446 | } | ||
| 447 | } | ||
| 448 | parseLoaders(node, all, toLoad); | ||
| 449 | } | ||
| 450 | } | ||
| 451 | } | ||
| 452 | |||
| 453 | |||
| 454 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 455 | |||
| 456 | /** @private **/ | ||
| 457 | override protected function _progressHandler(event:Event):void { | ||
| 458 | if (_dispatchProgress) { | ||
| 459 | var bl:uint = _cachedBytesLoaded; | ||
| 460 | var bt:uint = _cachedBytesTotal; | ||
| 461 | _calculateProgress(); | ||
| 462 | if (_cachedBytesLoaded != _cachedBytesTotal && (bl != _cachedBytesLoaded || bt != _cachedBytesTotal)) { | ||
| 463 | dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this)); | ||
| 464 | } | ||
| 465 | } else { | ||
| 466 | _cacheIsDirty = true; | ||
| 467 | } | ||
| 468 | } | ||
| 469 | |||
| 470 | /** @private **/ | ||
| 471 | override protected function _passThroughEvent(event:Event):void { | ||
| 472 | if (event.target != _loadingQueue) { | ||
| 473 | super._passThroughEvent(event); | ||
| 474 | } | ||
| 475 | } | ||
| 476 | |||
| 477 | /** @private **/ | ||
| 478 | override protected function _receiveDataHandler(event:Event):void { | ||
| 479 | try { | ||
| 480 | _content = new XML(_loader.data); | ||
| 481 | } catch (error:Error) { | ||
| 482 | _content = _loader.data; | ||
| 483 | _failHandler(new LoaderEvent(LoaderEvent.ERROR, this, error.message)); | ||
| 484 | return; | ||
| 485 | } | ||
| 486 | _initted = true; | ||
| 487 | |||
| 488 | _loadingQueue = new LoaderMax({name:this.name + "_Queue"}); | ||
| 489 | _parsed = new LoaderMax({name:this.name + "_ParsedLoaders", paused:true}); | ||
| 490 | parseLoaders(_content as XML, _parsed, _loadingQueue); | ||
| 491 | if (_parsed.numChildren == 0) { | ||
| 492 | _parsed.dispose(false); | ||
| 493 | _parsed = null; | ||
| 494 | } | ||
| 495 | if (_loadingQueue.getChildren(true, true).length == 0) { | ||
| 496 | _loadingQueue.empty(false); | ||
| 497 | _loadingQueue.dispose(false); | ||
| 498 | _loadingQueue = null; | ||
| 499 | } else { | ||
| 500 | _cacheIsDirty = true; | ||
| 501 | _changeQueueListeners(true); | ||
| 502 | _loadingQueue.load(false); | ||
| 503 | } | ||
| 504 | |||
| 505 | dispatchEvent(new LoaderEvent(LoaderEvent.INIT, this)); | ||
| 506 | if (_loadingQueue == null || (this.vars.integrateProgress == false)) { | ||
| 507 | _completeHandler(event); | ||
| 508 | } | ||
| 509 | } | ||
| 510 | |||
| 511 | /** @private **/ | ||
| 512 | override protected function _completeHandler(event:Event=null):void { | ||
| 513 | _calculateProgress(); | ||
| 514 | if (this.progress == 1) { | ||
| 515 | _changeQueueListeners(false); | ||
| 516 | super._completeHandler(event); | ||
| 517 | } | ||
| 518 | } | ||
| 519 | |||
| 520 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 521 | |||
| 522 | /** @inheritDoc The purpose of the override is so that we can return 1 in rare cases where the XML file literally is empty (bytesTotal == 0) which is verified when _initted == true. **/ | ||
| 523 | override public function get progress():Number { | ||
| 524 | return (this.bytesTotal != 0) ? _cachedBytesLoaded / _cachedBytesTotal : (_status == LoaderStatus.COMPLETED || _initted) ? 1 : 0; | ||
| 525 | } | ||
| 526 | |||
| 527 | } | ||
| 528 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | CHANGE LOG : GREENSOCK LOADERMAX SYSTEM | ||
| 2 | ---------------------------------------- | ||
| 3 | |||
| 4 | 2010-09-15 | ||
| 5 | --------------------------------------------- | ||
| 6 | LoaderMax 1.46 | ||
| 7 | ContentDisplay 1.46 | ||
| 8 | FlexContentDisplay 1.46 | ||
| 9 | - Fixed issue with ContentDisplay and FlexContentDisplay that could cause a Video to be displayed in the wrong proportions (this bug was introduced in version 1.43) | ||
| 10 | - Worked around bug in Flex that caused FlexContentDisplay's width and height properties to always report as 0. | ||
| 11 | |||
| 12 | 2010-09-14 | ||
| 13 | --------------------------------------------- | ||
| 14 | SWFLoader 1.4 | ||
| 15 | LoaderMax 1.45 | ||
| 16 | - Fixed issue that could cause a SWFLoader's internal Loader to not get closed if cancel() or unload() or dispose() is called before the swf has loaded enough to initialize its first frame. | ||
| 17 | |||
| 18 | 2010-09-10 | ||
| 19 | --------------------------------------------- | ||
| 20 | MP3Loader 1.4 | ||
| 21 | - Improved handing of the "duration" property so that it constantly updates its estimated value (the real duration cannot be determined with 100% accuracy until the file is fully loaded - that's just a limitatin of Flash). | ||
| 22 | - Added "initThreshold" special property to MP3Loader that allows you to specify a minimum bytesLoaded that must be reached before the INIT event gets dispatched which means you can set it to larger numbers to ensure a more accurate "duration" property when INIT is dispatched. The default is 102400 bytes (100k) | ||
| 23 | |||
| 24 | 2010-09-09 | ||
| 25 | --------------------------------------------- | ||
| 26 | LoaderMax 1.43 | ||
| 27 | ContentDisplay 1.43 | ||
| 28 | FlexContentDisplay 1.43 | ||
| 29 | VideoLoader 1.4 | ||
| 30 | - Added scaleMode, centerRegistration, hAlign, vAlign, crop, fitWidth, fitHeight, bgColor, and bgAlpha properties to ContentDisplay and FlexContentDisplay so that you can set all of those properties even AFTER creating the associated ImageLoader/SWFLoader/VideoLoader. Previously, the only way to set those properties was through the vars object of the loader. | ||
| 31 | - Fixed issue in VideoLoader that could cause very short (in duration) videos to not be sized correctly (and may be invisible) when autoPlay was set to false. | ||
| 32 | |||
| 33 | 2010-09-06 | ||
| 34 | --------------------------------------------- | ||
| 35 | LoaderMax 1.42 | ||
| 36 | - Changed data type of the return value of LoaderMax.parse() to "*" to avoid compiler errors when developers forget to cast their variable, like var image:ImageLoader = LoaderMax.parse("photo.jpg") as ImageLoader | ||
| 37 | |||
| 38 | 2010-09-05 | ||
| 39 | --------------------------------------------- | ||
| 40 | LoaderMax 1.41 | ||
| 41 | - Changed the name of the new LoaderMax "steppedProgress" property to "rawProgress" and improved its accuracy inbetween loads so that it is updated each time there's a PROGRESS event instead of only when a child loader fully completes. | ||
| 42 | |||
| 43 | 2010-09-01 | ||
| 44 | --------------------------------------------- | ||
| 45 | LoaderMax 1.4 | ||
| 46 | DisplayObjectLoader 1.31 | ||
| 47 | - Added a new "steppedProgress" property to LoaderMax that is based solely on the ratio of child loaders that have completed loading compared to those that haven't - this calculation does not concern itself whatsoever with bytesLoaded and bytesTotal. See docs for details. | ||
| 48 | - Changed the data type that the static getLoader() method returns to "*" instead of LoaderCore in order to make it easier on developers. Previously, for example, playing a VideoLoader would need to be done like (LoaderMax.getLoader("myVideoLoader") as VideoLoader).playVideo() but now it can simply be LoaderMax.getLoader("myVideoLoader").playVideo() | ||
| 49 | - Fixed minor problem with the forced garbage collection routine in SWFLoader and ImageLoader that gets called after unload() and dispose(true). | ||
| 50 | |||
| 51 | 2010-08-30 | ||
| 52 | --------------------------------------------- | ||
| 53 | LoaderMax 1.31 | ||
| 54 | - Fixed problem in LoaderMax.prependURLs() and LoaderMax.replaceURLText() that could cause an error if the includeNested parameter was set to true and there were nested child loaders. | ||
| 55 | |||
| 56 | 2010-08-12 | ||
| 57 | --------------------------------------------- | ||
| 58 | VideoLoader 1.32 | ||
| 59 | - Fixed VideoLoader's default autoPlay to be true instead of false (the documentation said the default was true but the actual behavior indicated false) | ||
| 60 | - Worked around bug in Flash that prevented metaData from being received by a NetStream (in VideoLoader) if pause() was called before the client's onMetaData callback was called. So in very rare circumstances (depending on how the flv was encoded), metaData simply wasn't received by VideoLoader, causing the INIT event to never be dispatched in that case. | ||
| 61 | |||
| 62 | 2010-08-09 | ||
| 63 | ---------------------------------------------- | ||
| 64 | (all LoaderMax classes) 1.3 | ||
| 65 | - Added new com.greensock.loading.data package with classes for defining vars objects for each type of loader which enables strict data typing and code hinting. For example, XMLoaderVars, LoaderMaxVars, SWFLoaderVars, etc. | ||
| 66 | - Made all LoaderMax classes compatible with the new "vars" objects | ||
| 67 | - Changed default MP3Loader autoPlay value from false to true in order to make it consistent with VideoLoader and SWFLoader | ||
| 68 | - Prevented parsed loaders that an XMLLoader finds inside XML from having their size audited automatically when their "load" attribute was set to "false". | ||
| 69 | - Fixed missing removeEventListener() inside LoaderMax that was listening for "dispose" events which could cause an error to be thrown if autoDispose was set to true on both a LoaderMax and its child. | ||
| 70 | |||
| 71 | 2010-08-07 | ||
| 72 | ---------------------------------------------- | ||
| 73 | VideoLoader 1.24 | ||
| 74 | MP3Loader 1.24 | ||
| 75 | LoaderMax 1.24 | ||
| 76 | - Added a bunch of capabilities to MP3Loader for controlling playback, like playSound(), pauseSound(), gotoSoundTime(), volume, playProgress, duration, soundTime, soundPaused, and some extra event dispatching like SOUND_PLAY, SOUND_PAUSE, SOUND_COMPLETE, and PLAY_PROGRESS | ||
| 77 | - Added dispatching of VIDEO_PROGRESS events from VideoLoader | ||
| 78 | - Worked around a bug in Adobe's NetStream class that prevented the proper loading of a video file after the loader was either canceled or unloaded (after the NetStream's close() method was called, no subsequent files could be played properly). | ||
| 79 | - Updated ASDocs | ||
| 80 | |||
| 81 | 2010-08-05 | ||
| 82 | ---------------------------------------------- | ||
| 83 | SWFLoader 1.23 | ||
| 84 | XMLLoader 1.23 | ||
| 85 | - Fixed issue that could cause a SWFLoader or XMLLoader to prematurely dispatch its COMPLETE event in a very rare scenario, like if a nested loader inside a swf dynamically inserted a new (more deeply) nested loader right before it would normally dispatch its COMPLETE event. | ||
| 86 | |||
| 87 | 2010-08-04 | ||
| 88 | ---------------------------------------------- | ||
| 89 | LoaderMax 1.23 | ||
| 90 | - Fixed issue that could cause a LoaderMax instance not to fire its COMPLETE event if new child loaders were added to it while it was in the process of loading its children. | ||
| 91 | |||
| 92 | 2010-07-31 | ||
| 93 | ---------------------------------------------- | ||
| 94 | SWFLoader 1.22 | ||
| 95 | - Worked around bug in Firefox version of Flash Player that could cause Adobe's Loader class not to report bytesLoaded and bytesTotal properly on swfs that are a particular size and gzip is enabled on the server (VERY rare). It could prevent SWFLoader from dispatching its COMPLETE event. | ||
| 96 | |||
| 97 | 2010-07-30 | ||
| 98 | ---------------------------------------------- | ||
| 99 | SWFLoader 1.21 | ||
| 100 | XMLLoader 1.21 | ||
| 101 | - Changed the default ApplicationDomain in SWFLoader to child (new ApplicationDomain(ApplicationDomain.currentDomain)) whereas previously it was same (ApplicationDomain.currentDomain) because several users were loading multiple swfs that used the same class/package which caused conflicts. Of course they could define a custom LoaderContext using the "context" special property, but the typical user doesn't understand what a LoaderContext is really, so it seemed safest to change the default to the safer "child" option. | ||
| 102 | - Updated ASDocs | ||
| 103 | |||
| 104 | 2010-07-28 | ||
| 105 | ---------------------------------------------- | ||
| 106 | (all LoaderMax classes) 1.2 | ||
| 107 | - Added "defaultAuditSize" static property to LoaderMax to give developers control of the default auditSize special vars property for LoaderMax instances. | ||
| 108 | - Added "data" property to the LoaderEvent class to store variable data like for VideoLoader's VIDEO_CUE_POINT event's cue point info. | ||
| 109 | - Added conditional logic so that Security.allowDomain() isn't called from an AIR app (AIR apps will burp on Security.allowDomain()) | ||
| 110 | - Updated ASDocs | ||
| 111 | |||
| 112 | 2010-07-23 | ||
| 113 | ---------------------------------------------- | ||
| 114 | LoaderMax 1.195 | ||
| 115 | SWFLoader 1.195 | ||
| 116 | XMLLoader 1.195 | ||
| 117 | - Changed the data type that getLoader() returns to "*" instead of LoaderCore in order to make it easier on developers. Previously, for example, playing a VideoLoader would need to be done like (LoaderMax.getLoader("myVideoLoader") as VideoLoader).playVideo() but now it can simply be LoaderMax.getLoader("myVideoLoader").playVideo() | ||
| 118 | |||
| 119 | 2010-07-17 | ||
| 120 | ---------------------------------------------- | ||
| 121 | LoaderMax 1.194 | ||
| 122 | DisplayObjectLoader 1.194 | ||
| 123 | - Significantly reduced brief RAM usage when loading images and/or swfs. Previously, BitmapData.draw() was used to check security restrictions in loaded assets which caused a temporary spike in RAM usage even though the BitmapData object was only 1 pixel tall and 1 pixel wide. | ||
| 124 | |||
| 125 | 2010-07-15 | ||
| 126 | ---------------------------------------------- | ||
| 127 | LoaderMax 1.193 | ||
| 128 | XMLLoader 1.192 | ||
| 129 | - Fixed issue that could cause a LoaderMax instance to cancel and start reloading a file unnecessarily when prioritize() is called on a child loader that has already completed loading. | ||
| 130 | - Worked around bug in Flash Player for Firefox that caused Adobe's URLLoader to incorrectly report its bytesLoaded as less than bytesTotal (only on very small files) even after its COMPLETE event had been dispatched, causing XMLLoader not to dispatch its COMPLETE event properly. | ||
| 131 | |||
| 132 | 2010-07-14 | ||
| 133 | ---------------------------------------------- | ||
| 134 | VideoLoader 1.192 | ||
| 135 | LoaderMax 1.192 | ||
| 136 | DisplayObjectLoader 1.192 | ||
| 137 | - Worked around Flash bug that prevented the VIDEO_BUFFER_FULL from being dispatched in VideoLoader when autoPlay was set to false. | ||
| 138 | - Fixed issue that could cause an ImageLoader or SWFLoader not to properly cancel() (it could still load in the background in very specific rare situations) | ||
| 139 | |||
| 140 | 2010-07-09 | ||
| 141 | ---------------------------------------------- | ||
| 142 | MP3Loader 1.141 | ||
| 143 | - Fixed problem where an MP3Loader's content could be null after its loading was canceled. | ||
| 144 | |||
| 145 | 2010-07-08 | ||
| 146 | ---------------------------------------------- | ||
| 147 | XMLLoader 1.191 | ||
| 148 | - Fixed issue that could cause an XMLLoader not to dispatch its COMPLETE event if the XML file was completely empty (bytesTotal of 0) | ||
| 149 | - Worked around a bug in the Flash Player for Chrome that caused Adobe's URLLoader to always report a bytesTotal of zero for very large XML files that were loaded with gzip enabled on the server (it only affected very large XML files) | ||
| 150 | |||
| 151 | 2010-06-30 | ||
| 152 | ---------------------------------------------- | ||
| 153 | XMLLoader 1.19 | ||
| 154 | LoaderMax 1.19 | ||
| 155 | SelfLoader 1.0 | ||
| 156 | - Worked around a bug in Flash Builder that caused it not to recognize XMLLoader for code hinting, etc. | ||
| 157 | - Added SelfLoader for tracking the current swf's loading progress | ||
| 158 | |||
| 159 | 2010-06-28 | ||
| 160 | ---------------------------------------------- | ||
| 161 | VideoLoader 1.18 | ||
| 162 | - Fixed issue that could cause a video to autoPlay even if autoPlay was set to false. This only happened in rare scenarios. | ||
| 163 | |||
| 164 | 2010-06-24 | ||
| 165 | ---------------------------------------------- | ||
| 166 | ContentDisplay 1.17 | ||
| 167 | FlexContentDisplay 1.17 | ||
| 168 | VideoLoader 1.17 | ||
| 169 | - Fixed crop feature that could incorrectly scale a video or an swf that had scriptAccessDenied = true. | ||
| 170 | |||
| 171 | 2010-06-23 | ||
| 172 | ---------------------------------------------- | ||
| 173 | ImageLoader 1.15 | ||
| 174 | SWFLoader 1.15 | ||
| 175 | VideoLoader 1.15 | ||
| 176 | XMLLoader 1.15 | ||
| 177 | ContentDisplay 1.15 | ||
| 178 | FlexContentDisplay 1.15 | ||
| 179 | - Added a new "crop" special property for SWFLoader, ImageLoader, and VideoLoader. | ||
| 180 | - Adjusted SWFLoader so that the swf's native size is what is factored into the scaleMode and alignement rather than its getBounds(). | ||
| 181 | |||
| 182 | 2010-06-22 | ||
| 183 | ---------------------------------------------- | ||
| 184 | (all LoaderMax classes) 1.14 | ||
| 185 | - Added ability to change a loader's url on the fly | ||
| 186 | - When a loader's url changes, it now resets its status to READY (unless it is paused in which case it will remain PAUSED). | ||
| 187 | - Implemented unloadAndStop() internally in SWFLoader and ImageLoader for swfs that are published to Flash Player 10 and later. This is just an added layer of protection against gc issues. | ||
| 188 | |||
| 189 | 2010-06-21 | ||
| 190 | ---------------------------------------------- | ||
| 191 | LoaderCore 1.12 | ||
| 192 | LoaderItem 1.12 | ||
| 193 | - Prevented PROGRESS event from being dispatched when a loader is disposed | ||
| 194 | - Added the dispatch of an ERROR LoaderEvent when an alternateURL is defined and the initial url fails | ||
| 195 | |||
| 196 | 2010-06-18 | ||
| 197 | ---------------------------------------------- | ||
| 198 | (all LoaderMax classes) 1.11 | ||
| 199 | - Added "alternateURL" property to all LoaderItems that allows you to define an alternate URL to load from if the original URL fails. | ||
| 200 | - VideoLoader now dispatches a VIDEO_PLAY event when autoPlay is true and the video initially loads and plays. | ||
| 201 | |||
| 202 | 2010-06-17 | ||
| 203 | ---------------------------------------------- | ||
| 204 | (all LoaderMax classes) 1.1 | ||
| 205 | - Added new "loadTime" property to all loaders which reports the number of seconds elapsed during the load. | ||
| 206 | - Fixed issue in SWFLoader that could cause it to stall if canceled before the swf had dispatched its INIT event. | ||
| 207 | - Altered VideoLoader to better handle a situation where metaData isn't received from the video being loaded. | ||
| 208 | - When XMLLoader encounters malformed XML it will now dispatch a LoaderEvent.ERROR. The "text" property of the LoaderEvent will describe the error. | ||
| 209 | - Added automatic trace() of all errors to make debugging easier. | ||
| 210 | |||
| 211 | 2010-06-17 | ||
| 212 | ---------------------------------------------- | ||
| 213 | LoaderMax 1.02 | ||
| 214 | LoaderCore 1.02 | ||
| 215 | - Improved status recognition in LoaderMax instances so that if a child was paused and the LoaderMax completed, when load() is called it will check again to see if any children were unpaused or failed and act accordingly, loading them if they're unpaused at that point. | ||
| 216 | |||
| 217 | 2010-06-16 | ||
| 218 | ---------------------------------------------- | ||
| 219 | LoaderMax 1.01 | ||
| 220 | VideoLoader 1.01 | ||
| 221 | - Fixed issue that could cause a LoaderMax not to dispatch its final PROGRESS event if it's not in the process of loading and its children have independently loaded fully. | ||
| 222 | - Fixed issue that could cause a video that doesn't have autoPlay:true to briefly play audio just as its buffer is filled (very brief). | ||
| 223 | |||
| 224 | 2010-06-16 (version 1.0) | ||
| 225 | ---------------------------------------------- | ||
| 226 | - Added "paused" property to VideoLoader | ||
| 227 | - Changed data type of SWFLoader's, ImageLoader's, VideoLoader's, ContentDisplay's, and FlexContentDisplay's rawContent property to * in order to reduce questions about compile-time errors when developers don't understand the concept of casting. | ||
| 228 | - Added "bufferMode" to VideoLoader | ||
| 229 | - Changed "loops" property in MP3Loader and "loop" property in VideoLoader to "repeat" to be consistent with TweenMax/TimelineMax (and with each other). | ||
| 230 | - Fixed problem that could cause a SWF to deny script access if it had NetStreams that hadn't started yet | ||
| 231 | |||
| 232 | 2010-06-04 (version 0.993) | ||
| 233 | ---------------------------------------------- | ||
| 234 | - Added "flushContent" parameter to the dispose() method so that if you want to completely destroy an instance, you can dispose(true) instead of unload() and dispose(). dispose(true) also destroys the ContentDisplay associated with any ImageLoaders, SWFLoaders, or VideoLoaders (removing them from the display list if necessary). | ||
| 235 | - Eliminated error that could be thrown if you use LoaderMax.getLoader() or LoaderMax.getContent() before any loaders are created. | ||
| 236 | - Added dispose() method to ContentDisplay and FlexContentDisplay | ||
| 237 | |||
| 238 | 2010-06-12 (version 0.992) | ||
| 239 | ---------------------------------------------- | ||
| 240 | - Fixed bug that could cause a SWFLoader or XMLLoader not to fire its COMPLETE event if it had an estimatedBytes defined and recognized sub-LoaderMax instances didn't have estimatedBytes defined and didn't load quickly enough. | ||
| 241 | |||
| 242 | 2010-06-10 (version 0.99) | ||
| 243 | ---------------------------------------------- | ||
| 244 | - Introduced new LoaderEvent class for easier event management | ||
| 245 | - Many of the LoaderEvents essentially bubble through Loaders, so the LoaderEvent's "target" is always the originating loader and the "currentTarget" can be the LoaderMax instance. For example, if you nest an ImageLoader in a LoaderMax and listen for LoaderEvent.ERROR events on that LoaderMax and the ImageLoader throws an error, your listener will receive a LoaderEvent whose target points to the ImageLoader and currentTarget points to the LoaderMax. | ||
| 246 | - Revamped most of the event architecture in the system, making it more robust | ||
| 247 | - Introduced FAIL, CHILD_OPEN, CHILD_PROGRESS, CHILD_COMPLETE, CHILD_CANCEL, and CHILD_FAIL events. | ||
| 248 | - You can listen for CHILD_* events on XMLLoaders and SWFLoaders too in order to get information about any nested loaders that are discovered in the XML/SWF. | ||
| 249 | - Added "httpStatus" property to LoaderItems | ||
| 250 | - Changed VideoLoader's resumeVideo() to playVideo() | ||
| 251 | - Changed VideoLoader's seekVideo() to gotoVideoTime() | ||
| 252 | |||
| 253 | 2010-06-09 (version 0.98) | ||
| 254 | ---------------------------------------------- | ||
| 255 | - Changed "prependChildrenURLs()" to "prependURLs()" in LoaderMax | ||
| 256 | - Added LoaderMax.parse() method for automatically creating the appropriate type of loader based on a url's file extension (you may pass an array as well in which case it will create a LoaderMax containing the necessary children) | ||
| 257 | - Added replaceURLText() method to LoaderMax | ||
| 258 | - Added ability for XMLLoader to recognize replaceURLText="" attribute | ||
| 259 | - Added "deblocking" and "loop" special properties to VideoLoader | ||
| 260 | - Eliminated unhandled error notifications | ||
| 261 | - Improved error reporting and identification of various types of loaders in trace() statements and toString(). | ||
| 262 | - Improved performance slightly | ||
| 263 | |||
| 264 | 2010-06-09 (version 0.972) | ||
| 265 | ---------------------------------------------- | ||
| 266 | - Added "smoothing" property to VideoLoader (enabled by default) | ||
| 267 | - Added "duration" property to VideoLoader | ||
| 268 | |||
| 269 | 2010-06-08 (version 0.971) | ||
| 270 | ---------------------------------------------- | ||
| 271 | - Fixed problem that could cause a SWFLoader or XMLLoader not to fire its COMPLETE event | ||
| 272 | |||
| 273 | 2010-06-08 (version 0.97) | ||
| 274 | ---------------------------------------------- | ||
| 275 | - Added VideoLoader | ||
| 276 | - Added ContentDisplay and FlexContentDisplay classes. | ||
| 277 | - Now ImageLoaders, SWFLoaders, and VideoLoaders will all return a ContentDisplay instance (a Sprite) as their content. The nice thing about ContentDisplay instances is that they have a "loader" property that gives you a way to reference the loader object that populated it. So if you need to unload() it or reload it or find out the loading progress, etc., that's all possible. | ||
| 278 | - Added a LoaderMax.contentDisplayClass property which you can set to FlexContentDisplay in order to make LoaderMax Flex-friendly. FlexContentDisplay extends UIComponent, fulfilling the Flex requirement. | ||
| 279 | - Reworked the cancel(), unload(), and dispose() logic internally | ||
| 280 | - Reduced file size slightly | ||
| 281 | - Changed the default "auditSize" special property to true in LoaderMax instances. Previously it was false, but it seems as though it will be a very useful feature that most developers will use and it will prevent some confusion with LoaderMax instances' progress and bytesTotal values being jumpy when estimatedBytes isn't used. Remember, whenever an estimatedBytes property is defined, it will be used instead of auditing the size with a URLStream (to improve performance). | ||
| 282 | - Prevented a ProgressEvent from being fired where the bytesLoaded == bytesTotal until any parsing and/or setting of the "content" property was completed. | ||
| 283 | - Prevented redundant ProgressEvents from being dispatched from a LoaderMax. | ||
| 284 | - Minor fixes | ||
| 285 | - Updated docs | ||
| 286 | |||
| 287 | 2010-06-04 (version 0.96) | ||
| 288 | ---------------------------------------------- | ||
| 289 | - Fixed issue with SWFLoader and XMLLoader that could cause the bytesLoaded to exceed bytesTotal if an estimatedBytes was defined that was too low and the swf/xml hadn't initted yet. | ||
| 290 | |||
| 291 | 2010-06-03 (version 0.95) | ||
| 292 | ---------------------------------------------- | ||
| 293 | - Added getSWFChild() to SWFLoader for finding DisplayObjects at the root of subloaded swfs | ||
| 294 | - Fixed problem that could cause XMLLoader not to fire its COMPLETE event in a certain situation | ||
| 295 | - Fixed bug in prepend() that replaced the first element instead of pushing it back | ||
| 296 | |||
| 297 | 2010-06-03 (version 0.93) | ||
| 298 | ---------------------------------------------- | ||
| 299 | - Fixed issue where the COMPLETE event could fire before the INIT event in an XMLLoader that found an empty <LoaderMax> node in the XML (and no other loaders) | ||
| 300 | - Fixed issue where an empty LoaderMax could report a progress of NaN instead of 0. | ||
| 301 | |||
| 302 | 2010-06-02 (version 0.92) | ||
| 303 | ---------------------------------------------- | ||
| 304 | - Enhanced SWFLoader to work around an Adobe bug in swfs that have TLF content which would mislabel content and fire INIT/COMPLETE events inappropriately. | ||
| 305 | |||
| 306 | 2010-06-02 (version 0.91) | ||
| 307 | ---------------------------------------------- | ||
| 308 | - Added "rawContent" property to ImageLoader and SWFLoader for retrieving raw content instead of the Sprite into which it was loaded. For example, an ImageLoader's "content" would be a Sprite whereas its rawContent would be a Bitmap (or a Loader if script access was denied). | ||
| 309 | - Removed "bitmap" property from ImageLoader because the generic "rawContent" property makes it redundant. | ||
| 310 | - Renamed CommonLoader to DisplayObjectLoader (you'd never use the class directly anyway) | ||
| 311 | |||
| 312 | 2010-06-01 (version 0.9) | ||
| 313 | ---------------------------------------------- | ||
| 314 | - Added prependChildrenURLs() to LoaderMax | ||
| 315 | - Added ability for XMLLoader to recognize prependChildrenURLs attribute in <LoaderMax> XML nodes | ||
| 316 | - Eliminated redundant ProgressEvent dispatching from XMLLoaders that found LoaderMax data inside XML. | ||
| 317 | |||
| 318 | 2010-06-01 (version 0.81) | ||
| 319 | ---------------------------------------------- | ||
| 320 | - Improved unload() and dispose() performance in ImageLoader and SWFLoader | ||
| 321 | - Images and swfs are now added at index 0 to the content Sprite instead of the top level | ||
| 322 | - Removed "offsetRegX" and "offsetRegY" special properties from ImageLoader and SWFLoader to reduce file size (they didn't seem super useful anyway). | ||
| 323 | - Fixed issue where a completed LoaderMax that was paused after having completed and then unload() is called would not load() again (refusing to unpause). | ||
| 324 | - Updated docs | ||
| 325 | |||
| 326 | 2010-06-01 (version 0.8) | ||
| 327 | ---------------------------------------------- | ||
| 328 | - Changed behavior of ImageLoader and SWFLoader so that their "content" property always returns a Sprite which serves as a container for the remote content. This Sprite is immediately available, making development tasks easier. | ||
| 329 | - Added the ability to have images and swfs scale to fit inside the width/height defined for the ImageLoader or SWFLoader with various scaleModes like "proportionalInside", "proportionalOutside", "stretch", "widthOnly", "heightOnly", and "none" | ||
| 330 | - Added hAlign, vAlign, bgColor, bgAlpha, offsetRegX, and offsetRegY special properties for ImageLoader and SWFLoader | ||
| 331 | - Updated XMLLoader so that it recognizes the various new special properties available in ImageLoader and SWFLoader | ||
| 332 | |||
| 333 | 2010-05-29 (version 0.71) | ||
| 334 | ---------------------------------------------- | ||
| 335 | - When XMLLoader finds LoaderMax-related data inside the XML, it will now audit the size of any that don't have an estimatedSize defined. | ||
| 336 | - Fixed issue that could cause auditedSize to incorrectly report false. | ||
| 337 | |||
| 338 | 2010-05-29 (version 0.7) | ||
| 339 | ---------------------------------------------- | ||
| 340 | - When auditSize() is called and the URLStream fails because of an IO_ERROR, the loader will now set its status to FAILED and generate an error event which also takes it out of consideration when determining a LoaderMax's progress. | ||
| 341 | - Fixed a garbage collection problem | ||
| 342 | - Updated docs | ||
| 343 | |||
| 344 | 2010-05-28 (version 0.65) | ||
| 345 | ---------------------------------------------- | ||
| 346 | - Added DataLoader class for loading generic text, binary, and URL-encoded variables | ||
| 347 | - Added CSSLoader class for loading StyleSheet information. | ||
| 348 | - Added onOpen to docs for all loaders | ||
| 349 | - Fixed error that was thrown when a swf was loaded whose root was not a MovieClip | ||
| 350 | |||
| 351 | 2010-05-27 | ||
| 352 | ---------------------------------------------- | ||
| 353 | - XMLLoader now recognizes a "context" attribute inside XML-driven loaders, like <SWFLoader name="swf1" url="swf/file.swf" context="separate" />. The default value is "own" and other options are "child" and "separate". | ||
| 354 | - ImageLoader and SWFLoader now recognize the "blendMode" special property so that you can set the image's/swf's blendMode as soon as it loads. | ||
| 355 | - If SWFLoader loads an AVM1Movie (AS1/AS2), it will toggle the scriptAccessDenied to true and the content will refer to the Loader object instead of the root of the swf for security purposes. | ||
| 356 | - Minor updates to docs | ||
| 357 | |||
| 358 | 2010-05-26 | ||
| 359 | ---------------------------------------------- | ||
| 360 | - Added an auditSize special vars property to LoaderMax. See ASDocs for details about functionality | ||
| 361 | - Added auditSize() method and auditedSize property to all loaders | ||
| 362 | - Added logic in ImageLoader and SWFLoader to fall back to a more restricted mode in terms of script access when a security error is thrown due to a missing or malconfigured crossdomain.xml file. This improves the likelihood that the content will still load even if there was a security error. | ||
| 363 | - Added LoaderMax.SCRIPT_ACCESS_DENIED event dispatching along with an onScriptAccessDenied special vars property | ||
| 364 | - Added a new scriptAccessDenied property that you can check in order to determine whether or not you can perform operations like BitmapData.draw() on ImageLoader/SWFLoader content. | ||
| 365 | - Tweaked error handling so that unhandled errors aren't thrown. | ||
| 366 | - Added dispatching of IOErrorEvents, SecurityErrorEvents, and HTTPStatusEvents (you can set them up normally or with onIOError, onSecurityError, and onHTTPStatus special vars properties) | ||
| 367 | |||
| 368 | 2010-05-25 | ||
| 369 | ---------------------------------------------- | ||
| 370 | - Changed LoaderMax's getAllLoaders() to getChildren() | ||
| 371 | - Changed LoaderMax's getLoadersByStatus() to getChildrenByStatus() | ||
| 372 | - Changed LoaderMax's getLoaderIndex() to getChildIndex() | ||
| 373 | - Added LoaderMax.defaultEstimatedBytes so that you can define any default value for new Loaders that don't have an estimatedBytes property defined in the vars object. | ||
| 374 | - Changed the default estimatedBytes to 20000 instead of 1000. | ||
| 375 | - Added the ability for ImageLoaders and SWFLoaders to recognize a "visible" property in the vars object so that you can set the object's visible property. | ||
| 376 | - Removed "loaders" property of LoaderMax | ||
| 377 | - Added getClass() method to SWFLoader | ||
| 378 | - Minor updates to docs |
| 1 | /** | ||
| 2 | * VERSION: 1.31 | ||
| 3 | * DATE: 2010-09-01 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.core { | ||
| 8 | import com.greensock.events.LoaderEvent; | ||
| 9 | import com.greensock.loading.LoaderMax; | ||
| 10 | import com.greensock.loading.LoaderStatus; | ||
| 11 | import com.greensock.loading.display.ContentDisplay; | ||
| 12 | |||
| 13 | import flash.display.DisplayObject; | ||
| 14 | import flash.display.Loader; | ||
| 15 | import flash.display.Sprite; | ||
| 16 | import flash.events.ErrorEvent; | ||
| 17 | import flash.events.Event; | ||
| 18 | import flash.events.ProgressEvent; | ||
| 19 | import flash.net.LocalConnection; | ||
| 20 | import flash.system.ApplicationDomain; | ||
| 21 | import flash.system.Capabilities; | ||
| 22 | import flash.system.LoaderContext; | ||
| 23 | import flash.system.Security; | ||
| 24 | import flash.system.SecurityDomain; | ||
| 25 | /** | ||
| 26 | * Serves as the base class for SWFLoader and ImageLoader. There is no reason to use this class on its own. | ||
| 27 | * Please refer to the documentation for the other classes. | ||
| 28 | * <br /><br /> | ||
| 29 | * | ||
| 30 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 31 | * | ||
| 32 | * @author Jack Doyle, jack@greensock.com | ||
| 33 | */ | ||
| 34 | public class DisplayObjectLoader extends LoaderItem { | ||
| 35 | /** @private the Sprite to which the EVENT_LISTENER was attached for forcing garbage collection after 1 frame (improves performance especially when multiple loaders are disposed at one time). **/ | ||
| 36 | protected static var _gcDispatcher:DisplayObject; | ||
| 37 | /** @private **/ | ||
| 38 | protected static var _gcCycles:uint = 0; | ||
| 39 | /** @private **/ | ||
| 40 | protected var _loader:Loader; | ||
| 41 | /** @private **/ | ||
| 42 | protected var _sprite:Sprite; | ||
| 43 | /** @private **/ | ||
| 44 | protected var _context:LoaderContext; | ||
| 45 | /** @private **/ | ||
| 46 | protected var _initted:Boolean; | ||
| 47 | /** @private used by SWFLoader when the loader is canceled before the SWF ever had a chance to init which causes garbage collection issues. We slip into stealthMode at that point, wait for it to init, and then cancel the _loader's loading.**/ | ||
| 48 | protected var _stealthMode:Boolean; | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Constructor | ||
| 52 | * | ||
| 53 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content | ||
| 54 | * @param vars An object containing optional parameters like <code>estimatedBytes, name, autoDispose, onComplete, onProgress, onError</code>, etc. For example, <code>{estimatedBytes:2400, name:"myImage1", onComplete:completeHandler}</code>. | ||
| 55 | */ | ||
| 56 | public function DisplayObjectLoader(urlOrRequest:*, vars:Object=null) { | ||
| 57 | super(urlOrRequest, vars); | ||
| 58 | _refreshLoader(false); | ||
| 59 | if (LoaderMax.contentDisplayClass is Class) { | ||
| 60 | _sprite = new LoaderMax.contentDisplayClass(this); | ||
| 61 | if (!_sprite.hasOwnProperty("rawContent")) { | ||
| 62 | throw new Error("LoaderMax.contentDisplayClass must be set to a class with a 'rawContent' property, like com.greensock.loading.display.ContentDisplay"); | ||
| 63 | } | ||
| 64 | } else { | ||
| 65 | _sprite = new ContentDisplay(this); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | /** @private Set inside ContentDisplay's or FlexContentDisplay's "loader" setter. **/ | ||
| 70 | public function setContentDisplay(contentDisplay:Sprite):void { | ||
| 71 | _sprite = contentDisplay; | ||
| 72 | } | ||
| 73 | |||
| 74 | /** @private **/ | ||
| 75 | override protected function _load():void { | ||
| 76 | _prepRequest(); | ||
| 77 | |||
| 78 | if (this.vars.context is LoaderContext) { | ||
| 79 | _context = this.vars.context; | ||
| 80 | } else if (_context == null && !_isLocal) { | ||
| 81 | _context = new LoaderContext(true, new ApplicationDomain(ApplicationDomain.currentDomain), SecurityDomain.currentDomain); //avoids some security sandbox headaches that plague many users. | ||
| 82 | } | ||
| 83 | if (Capabilities.playerType != "Desktop") { //AIR apps will choke on Security.allowDomain() | ||
| 84 | Security.allowDomain(_url); | ||
| 85 | } | ||
| 86 | |||
| 87 | _loader.load(_request, _context); | ||
| 88 | } | ||
| 89 | |||
| 90 | /** @private **/ | ||
| 91 | protected function _refreshLoader(unloadContent:Boolean=true):void { | ||
| 92 | if (_loader != null) { | ||
| 93 | //to avoid gc issues and get around a bug in Flash that incorrectly reports progress values on Loaders that were closed before completing, we must force gc and recreate the Loader altogether... | ||
| 94 | if (_status == LoaderStatus.LOADING) { | ||
| 95 | try { | ||
| 96 | _loader.close(); | ||
| 97 | } catch (error:Error) { | ||
| 98 | |||
| 99 | } | ||
| 100 | } | ||
| 101 | _loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, _progressHandler); | ||
| 102 | _loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, _completeHandler); | ||
| 103 | _loader.contentLoaderInfo.removeEventListener("ioError", _failHandler); | ||
| 104 | _loader.contentLoaderInfo.removeEventListener("securityError", _securityErrorHandler); | ||
| 105 | _loader.contentLoaderInfo.removeEventListener("httpStatus", _httpStatusHandler); | ||
| 106 | _loader.contentLoaderInfo.removeEventListener(Event.INIT, _initHandler); | ||
| 107 | if (unloadContent) { | ||
| 108 | try { | ||
| 109 | if (_loader.hasOwnProperty("unloadAndStop")) { //Flash Player 10 and later only | ||
| 110 | (_loader as Object).unloadAndStop(); | ||
| 111 | } else { | ||
| 112 | _loader.unload(); | ||
| 113 | } | ||
| 114 | } catch (error:Error) { | ||
| 115 | |||
| 116 | } | ||
| 117 | } | ||
| 118 | forceGC(_sprite, (this.hasOwnProperty("getClass")) ? 3 : 1); | ||
| 119 | } | ||
| 120 | _initted = false; | ||
| 121 | _loader = new Loader(); | ||
| 122 | _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, _progressHandler, false, 0, true); | ||
| 123 | _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _completeHandler, false, 0, true); | ||
| 124 | _loader.contentLoaderInfo.addEventListener("ioError", _failHandler, false, 0, true); | ||
| 125 | _loader.contentLoaderInfo.addEventListener("securityError", _securityErrorHandler, false, 0, true); | ||
| 126 | _loader.contentLoaderInfo.addEventListener("httpStatus", _httpStatusHandler, false, 0, true); | ||
| 127 | _loader.contentLoaderInfo.addEventListener(Event.INIT, _initHandler, false, 0, true); | ||
| 128 | } | ||
| 129 | |||
| 130 | /** @private works around bug in Flash Player that prevents SWFs from properly being garbage collected after being unloaded - for certain types of objects like swfs, this needs to be run more than once (spread out over several frames) to force Flash to properly garbage collect everything. **/ | ||
| 131 | public static function forceGC(dispatcher:DisplayObject, cycles:uint=1):void { | ||
| 132 | if (_gcCycles < cycles) { | ||
| 133 | _gcCycles = cycles; | ||
| 134 | if (_gcDispatcher == null) { | ||
| 135 | _gcDispatcher = dispatcher; | ||
| 136 | _gcDispatcher.addEventListener(Event.ENTER_FRAME, _forceGCHandler, false, 0, true); | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | /** @private **/ | ||
| 142 | protected static function _forceGCHandler(event:Event):void { | ||
| 143 | if (_gcCycles == 0) { | ||
| 144 | _gcDispatcher.removeEventListener(Event.ENTER_FRAME, _forceGCHandler); | ||
| 145 | _gcDispatcher = null; | ||
| 146 | } else { | ||
| 147 | _gcCycles--; | ||
| 148 | } | ||
| 149 | try { | ||
| 150 | new LocalConnection().connect("FORCE_GC"); | ||
| 151 | new LocalConnection().connect("FORCE_GC"); | ||
| 152 | } catch (error:Error) { | ||
| 153 | |||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 158 | override protected function _dump(scrubLevel:int=0, newStatus:int=LoaderStatus.READY, suppressEvents:Boolean=false):void { | ||
| 159 | if (scrubLevel == 1) { //unload | ||
| 160 | (_sprite as Object).rawContent = null; | ||
| 161 | } else if (scrubLevel == 2) { //dispose | ||
| 162 | (_sprite as Object).loader = null; | ||
| 163 | } else if (scrubLevel == 3) { //unload and dispose | ||
| 164 | (_sprite as Object).dispose(false, false); //makes sure the ContentDisplay is removed from its parent as well. | ||
| 165 | } | ||
| 166 | if (!_stealthMode) { | ||
| 167 | _refreshLoader(Boolean(scrubLevel != 2)); | ||
| 168 | } | ||
| 169 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 170 | } | ||
| 171 | |||
| 172 | /** @private **/ | ||
| 173 | protected function _determineScriptAccess():void { | ||
| 174 | if (!_scriptAccessDenied) { | ||
| 175 | if (!_loader.contentLoaderInfo.childAllowsParent) { | ||
| 176 | _scriptAccessDenied = true; | ||
| 177 | dispatchEvent(new LoaderEvent(LoaderEvent.SCRIPT_ACCESS_DENIED, this, "Error #2123: Security sandbox violation: " + this + ". No policy files granted access.")); | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | |||
| 183 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 184 | |||
| 185 | /** @private **/ | ||
| 186 | protected function _securityErrorHandler(event:ErrorEvent):void { | ||
| 187 | //If a security error is thrown because of a missing crossdomain.xml file for example and the user didn't define a specific LoaderContext, we'll try again without checking the policy file, accepting the restrictions that come along with it because typically people would rather have the content show up on the screen rather than just error out (and they can always check the scriptAccessDenied property if they need to figure out whether it's safe to do BitmapData stuff on it, etc.) | ||
| 188 | if (_context != null && _context.checkPolicyFile && !(this.vars.context is LoaderContext)) { | ||
| 189 | _context = new LoaderContext(false); | ||
| 190 | _scriptAccessDenied = true; | ||
| 191 | dispatchEvent(new LoaderEvent(LoaderEvent.SCRIPT_ACCESS_DENIED, this, event.text)); | ||
| 192 | _errorHandler(event); | ||
| 193 | _load(); | ||
| 194 | } else { | ||
| 195 | _failHandler(event); | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | /** @private **/ | ||
| 200 | protected function _initHandler(event:Event):void { | ||
| 201 | if (!_initted) { | ||
| 202 | _initted = true; | ||
| 203 | (_sprite as Object).rawContent = (_content as DisplayObject); | ||
| 204 | dispatchEvent(new LoaderEvent(LoaderEvent.INIT, this)); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 209 | |||
| 210 | /** A ContentDisplay object (a Sprite) that will contain the remote content as soon as the <code>INIT</code> event has been dispatched. This ContentDisplay can be accessed immediately; you do not need to wait for the content to load. **/ | ||
| 211 | override public function get content():* { | ||
| 212 | return _sprite; | ||
| 213 | } | ||
| 214 | |||
| 215 | /** | ||
| 216 | * The raw content that was successfully loaded <strong>into</strong> the <code>content</code> ContentDisplay | ||
| 217 | * Sprite which varies depending on the type of loader and whether or not script access was denied while | ||
| 218 | * attempting to load the file: | ||
| 219 | * | ||
| 220 | * <ul> | ||
| 221 | * <li>ImageLoader with script access granted: <code>flash.display.Bitmap</code></li> | ||
| 222 | * <li>ImageLoader with script access denied: <code>flash.display.Loader</code></li> | ||
| 223 | * <li>SWFLoader with script access granted: <code>flash.display.DisplayObject</code> (the swf's <code>root</code>)</li> | ||
| 224 | * <li>SWFLoader with script access denied: <code>flash.display.Loader</code> (the swf's <code>root</code> cannot be accessed because it would generate a security error)</li> | ||
| 225 | * </ul> | ||
| 226 | **/ | ||
| 227 | public function get rawContent():* { | ||
| 228 | return _content; | ||
| 229 | } | ||
| 230 | |||
| 231 | } | ||
| 232 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.3 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.core { | ||
| 8 | import com.greensock.events.LoaderEvent; | ||
| 9 | import com.greensock.loading.LoaderMax; | ||
| 10 | import com.greensock.loading.LoaderStatus; | ||
| 11 | |||
| 12 | import flash.display.DisplayObject; | ||
| 13 | import flash.events.Event; | ||
| 14 | import flash.events.EventDispatcher; | ||
| 15 | import flash.events.ProgressEvent; | ||
| 16 | import flash.net.LocalConnection; | ||
| 17 | import flash.system.Capabilities; | ||
| 18 | import flash.utils.Dictionary; | ||
| 19 | import flash.utils.getTimer; | ||
| 20 | |||
| 21 | /** Dispatched when the loader starts loading. **/ | ||
| 22 | [Event(name="open", type="com.greensock.events.LoaderEvent")] | ||
| 23 | /** Dispatched each time the <code>bytesLoaded</code> value changes while loading (indicating progress). **/ | ||
| 24 | [Event(name="progress", type="com.greensock.events.LoaderEvent")] | ||
| 25 | /** Dispatched when the loader completes. **/ | ||
| 26 | [Event(name="complete", type="com.greensock.events.LoaderEvent")] | ||
| 27 | /** Dispatched when the loader is canceled while loading which can occur either because of a failure or when a sibling loader is prioritized in a LoaderMax queue. **/ | ||
| 28 | [Event(name="cancel", type="com.greensock.events.LoaderEvent")] | ||
| 29 | /** Dispatched when the loader fails. **/ | ||
| 30 | [Event(name="fail", type="com.greensock.events.LoaderEvent")] | ||
| 31 | /** Dispatched when the loader experiences some type of error, like a SECURITY_ERROR or IO_ERROR. **/ | ||
| 32 | [Event(name="error", type="com.greensock.events.LoaderEvent")] | ||
| 33 | /** | ||
| 34 | * Serves as the base class for GreenSock loading tools like <code>LoaderMax, ImageLoader, XMLLoader, SWFLoader</code>, etc. | ||
| 35 | * There is no reason to use this class on its own. Please see the documentation for the other classes. | ||
| 36 | * <br /><br /> | ||
| 37 | * | ||
| 38 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 39 | * | ||
| 40 | * @author Jack Doyle, jack@greensock.com | ||
| 41 | */ | ||
| 42 | public class LoaderCore extends EventDispatcher { | ||
| 43 | /** @private **/ | ||
| 44 | public static const version:Number = 1.3; | ||
| 45 | |||
| 46 | /** @private **/ | ||
| 47 | protected static var _loaderCount:uint = 0; | ||
| 48 | /** @private **/ | ||
| 49 | protected static var _rootLookup:Dictionary = new Dictionary(false); | ||
| 50 | /** @private **/ | ||
| 51 | protected static var _isLocal:Boolean; | ||
| 52 | /** @private **/ | ||
| 53 | protected static var _globalRootLoader:LoaderMax; | ||
| 54 | /** @private **/ | ||
| 55 | protected static var _listenerTypes:Object = {onOpen:"open", | ||
| 56 | onInit:"init", | ||
| 57 | onComplete:"complete", | ||
| 58 | onProgress:"progress", | ||
| 59 | onCancel:"cancel", | ||
| 60 | onFail:"fail", | ||
| 61 | onError:"error", | ||
| 62 | onSecurityError:"securityError", | ||
| 63 | onHTTPStatus:"httpStatus", | ||
| 64 | onIOError:"ioError", | ||
| 65 | onScriptAccessDenied:"scriptAccessDenied", | ||
| 66 | onChildOpen:"childOpen", | ||
| 67 | onChildCancel:"childCancel", | ||
| 68 | onChildComplete:"childComplete", | ||
| 69 | onChildProgress:"childProgress", | ||
| 70 | onChildFail:"childFail"}; | ||
| 71 | /** @private **/ | ||
| 72 | protected static var _types:Object = {}; | ||
| 73 | /** @private **/ | ||
| 74 | protected static var _extensions:Object = {}; | ||
| 75 | |||
| 76 | /** @private **/ | ||
| 77 | protected var _cachedBytesLoaded:uint; | ||
| 78 | /** @private **/ | ||
| 79 | protected var _cachedBytesTotal:uint; | ||
| 80 | /** @private **/ | ||
| 81 | protected var _status:int; | ||
| 82 | /** @private **/ | ||
| 83 | protected var _prePauseStatus:int; | ||
| 84 | /** @private **/ | ||
| 85 | protected var _dispatchProgress:Boolean; | ||
| 86 | /** @private **/ | ||
| 87 | protected var _rootLoader:LoaderMax; | ||
| 88 | /** @private **/ | ||
| 89 | protected var _cacheIsDirty:Boolean; | ||
| 90 | /** @private **/ | ||
| 91 | protected var _auditedSize:Boolean; | ||
| 92 | /** @private **/ | ||
| 93 | protected var _dispatchChildProgress:Boolean; | ||
| 94 | /** @private **/ | ||
| 95 | protected var _type:String; | ||
| 96 | /** @private used to store timing information. When the loader begins loading, the startTime is stored here. When it completes or fails, it is set to the total elapsed time between when it started and ended. We reuse this variable like this in order to minimize size. **/ | ||
| 97 | protected var _time:uint; | ||
| 98 | /** @private **/ | ||
| 99 | protected var _content:*; | ||
| 100 | |||
| 101 | /** An object containing optional configuration details, typically passed through a constructor parameter. For example: <code>new SWFLoader("assets/file.swf", {name:"swf1", container:this, autoPlay:true, noCache:true})</code>. See the constructor's documentation for details about what special properties are recognized. **/ | ||
| 102 | public var vars:Object; | ||
| 103 | /** A name that you use to identify the loader instance. This name can be fed to the <code>getLoader()</code> or <code>getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". **/ | ||
| 104 | public var name:String; | ||
| 105 | /** When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is <strong>not</strong> unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>. **/ | ||
| 106 | public var autoDispose:Boolean; | ||
| 107 | |||
| 108 | /** | ||
| 109 | * Constructor | ||
| 110 | * | ||
| 111 | * @param vars An object containing optional parameters like <code>estimatedBytes, name, autoDispose, onComplete, onProgress, onError</code>, etc. For example, <code>{estimatedBytes:2400, name:"myImage1", onComplete:completeHandler}</code>. | ||
| 112 | */ | ||
| 113 | public function LoaderCore(vars:Object=null) { | ||
| 114 | this.vars = (vars != null) ? vars : {}; | ||
| 115 | this.name = (this.vars.name != undefined && this.vars.name != "") ? this.vars.name : "loader" + (_loaderCount++); | ||
| 116 | _cachedBytesLoaded = 0; | ||
| 117 | _cachedBytesTotal = (uint(this.vars.estimatedBytes) != 0) ? uint(this.vars.estimatedBytes) : LoaderMax.defaultEstimatedBytes; | ||
| 118 | this.autoDispose = Boolean(this.vars.autoDispose == true); | ||
| 119 | _status = (this.vars.paused == true) ? LoaderStatus.PAUSED : LoaderStatus.READY; | ||
| 120 | _auditedSize = Boolean(uint(this.vars.estimatedBytes) != 0 && this.vars.auditSize != true); | ||
| 121 | |||
| 122 | _rootLoader = (this.vars.requireWithRoot is DisplayObject) ? _rootLookup[this.vars.requireWithRoot] : _globalRootLoader; | ||
| 123 | |||
| 124 | if (_globalRootLoader == null) { | ||
| 125 | if (this.vars.__isRoot == true) { | ||
| 126 | return; | ||
| 127 | } | ||
| 128 | _globalRootLoader = _rootLoader = new LoaderMax({name:"root", __isRoot:true}); | ||
| 129 | _isLocal = Boolean((new LocalConnection( ).domain == "localhost") || Capabilities.playerType == "Desktop"); //alt method (Capabilities.playerType != "ActiveX" && Capabilities.playerType != "PlugIn") doesn't work when testing locally in an html wrapper | ||
| 130 | } | ||
| 131 | |||
| 132 | if (_rootLoader) { | ||
| 133 | _rootLoader.append(this); | ||
| 134 | } else { | ||
| 135 | _rootLookup[this.vars.requireWithRoot] = _rootLoader = new LoaderMax(); | ||
| 136 | _rootLoader.name = "subloaded_swf_" + this.vars.requireWithRoot.loaderInfo.url; | ||
| 137 | _rootLoader.append(this); | ||
| 138 | } | ||
| 139 | |||
| 140 | for (var p:String in _listenerTypes) { | ||
| 141 | if (p in this.vars && this.vars[p] is Function) { | ||
| 142 | this.addEventListener(_listenerTypes[p], this.vars[p], false, 0, true); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | /** | ||
| 148 | * Loads the loader's content, optionally flushing any previously loaded content first. For example, | ||
| 149 | * a LoaderMax may have already loaded 4 out of the 10 loaders in its queue but if you want it to | ||
| 150 | * flush the data and start again, set the <code>flushContent</code> parameter to <code>true</code> (it is | ||
| 151 | * <code>false</code> by default). | ||
| 152 | * | ||
| 153 | * @param flushContent If <code>true</code>, any previously loaded content in the loader will be flushed so that it loads again from the beginning. For example, a LoaderMax may have already loaded 4 out of the 10 loaders in its queue but if you want it to flush the data and start again, set the <code>flushContent</code> parameter to <code>true</code> (it is <code>false</code> by default). | ||
| 154 | */ | ||
| 155 | public function load(flushContent:Boolean=false):void { | ||
| 156 | var time:uint = getTimer(); | ||
| 157 | if (this.status == LoaderStatus.PAUSED) { //use this.status instead of _status so that LoaderMax instances have a chance to do their magic in the getter and make sure their status is calibrated properly in case any of its children changed status after the LoaderMax completed (maybe they were manually loaded or failed, etc.). | ||
| 158 | _status = (_prePauseStatus <= LoaderStatus.LOADING) ? LoaderStatus.READY : _prePauseStatus; | ||
| 159 | if (_status == LoaderStatus.READY && this is LoaderMax) { | ||
| 160 | time -= _time; //when a LoaderMax is resumed, we should offset the start time. | ||
| 161 | } | ||
| 162 | } | ||
| 163 | if (flushContent || _status == LoaderStatus.FAILED) { | ||
| 164 | _dump(1, LoaderStatus.READY); | ||
| 165 | } | ||
| 166 | |||
| 167 | if (_status == LoaderStatus.READY) { | ||
| 168 | _status = LoaderStatus.LOADING; | ||
| 169 | _time = time; | ||
| 170 | _load(); | ||
| 171 | dispatchEvent(new LoaderEvent(LoaderEvent.OPEN, this)); | ||
| 172 | } else if (_status == LoaderStatus.COMPLETED) { | ||
| 173 | _completeHandler(null); | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | /** @private Only called when load() was called and the _status was LoaderStatus.READY - we use this internally to make it simpler to extend (the conditional logic stays in the main <code>load()</code> method). **/ | ||
| 178 | protected function _load():void { | ||
| 179 | //override in subclasses | ||
| 180 | } | ||
| 181 | |||
| 182 | /** Pauses the loader immediately. This is the same as setting the <code>paused</code> property to <code>true</code>. Some loaders may not stop loading immediately in order to work around some garbage collection issues in the Flash Player, but they will stop as soon as possible after calling <code>pause()</code>. **/ | ||
| 183 | public function pause():void { | ||
| 184 | this.paused = true; | ||
| 185 | } | ||
| 186 | |||
| 187 | /** Unpauses the loader and resumes loading immediately. **/ | ||
| 188 | public function resume():void { | ||
| 189 | this.paused = false; | ||
| 190 | load(false); | ||
| 191 | } | ||
| 192 | |||
| 193 | /** | ||
| 194 | * If the loader is currently loading (<code>status</code> is <code>LoaderStatus.LOADING</code>), it will be canceled | ||
| 195 | * immediately and its status will change to <code>LoaderStatus.READY</code>. This does <strong>NOT</strong> pause the | ||
| 196 | * loader - it simply halts the progress and it remains eligible for loading by any of its parent LoaderMax instances. | ||
| 197 | * A paused loader, however, cannot be loaded by any of its parent LoaderMax instances until you unpause it (by either | ||
| 198 | * calling <code>resume()</code> or setting its <code>paused</code> property to false). | ||
| 199 | * @see #unload() | ||
| 200 | * @see #dispose() | ||
| 201 | **/ | ||
| 202 | public function cancel():void { | ||
| 203 | if (_status == LoaderStatus.LOADING) { | ||
| 204 | _dump(0, LoaderStatus.READY); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * @private | ||
| 210 | * Cancels, unloads, and/or disposes of the loader depending on the <code>scrubLevel</code>. This consolidates | ||
| 211 | * the actions into a single function to conserve file size and because many of the same tasks must | ||
| 212 | * be performed regardless of the scrubLevel, so this eliminates redundant code. | ||
| 213 | * | ||
| 214 | * @param scrubLevel 0 = cancel, 1 = unload, 2 = dispose, 3 = flush (like unload and dispose, but in the case of ImageLoaders, SWFLoaders, and VideoLoaders, it also removes the ContentDisplay from the display list) | ||
| 215 | * @param newStatus The new LoaderStatus to which the loader should be set. | ||
| 216 | * @param suppressEvents To prevent events from being dispatched (like CANCEL or DISPOSE or PROGRESS), set <code>suppressEvents</code> to <code>true</code>. | ||
| 217 | **/ | ||
| 218 | protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 219 | _content = null; | ||
| 220 | var isLoading:Boolean = Boolean(_status == LoaderStatus.LOADING); | ||
| 221 | if (_status == LoaderStatus.PAUSED && newStatus != LoaderStatus.PAUSED) { | ||
| 222 | _prePauseStatus = newStatus; | ||
| 223 | } else if (_status != LoaderStatus.DISPOSED) { | ||
| 224 | _status = newStatus; | ||
| 225 | } | ||
| 226 | if (isLoading) { | ||
| 227 | _time = getTimer() - _time; | ||
| 228 | } | ||
| 229 | if (_dispatchProgress && !suppressEvents && _status != LoaderStatus.DISPOSED) { | ||
| 230 | if (this is LoaderMax) { | ||
| 231 | _calculateProgress(); | ||
| 232 | } else { | ||
| 233 | _cachedBytesLoaded = 0; | ||
| 234 | } | ||
| 235 | dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this)); | ||
| 236 | } | ||
| 237 | if (isLoading && !suppressEvents) { | ||
| 238 | dispatchEvent(new LoaderEvent(LoaderEvent.CANCEL, this)); | ||
| 239 | } | ||
| 240 | if (newStatus == LoaderStatus.DISPOSED) { | ||
| 241 | if (!suppressEvents) { | ||
| 242 | dispatchEvent(new Event("dispose")); | ||
| 243 | } | ||
| 244 | for (var p:String in _listenerTypes) { | ||
| 245 | if (p in this.vars && this.vars[p] is Function) { | ||
| 246 | this.removeEventListener(_listenerTypes[p], this.vars[p]); | ||
| 247 | } | ||
| 248 | } | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | /** | ||
| 253 | * Removes any content that was loaded and sets <code>bytesLoaded</code> back to zero. When you | ||
| 254 | * <code>unload()</code> a LoaderMax instance, it will also call <code>unload()</code> on all of its | ||
| 255 | * children as well. If the loader is in the process of loading, it will automatically be canceled. | ||
| 256 | * | ||
| 257 | * @see #dispose() | ||
| 258 | **/ | ||
| 259 | public function unload():void { | ||
| 260 | _dump(1, LoaderStatus.READY); | ||
| 261 | } | ||
| 262 | |||
| 263 | /** | ||
| 264 | * Disposes of the loader and releases it internally for garbage collection. If it is in the process of loading, it will also | ||
| 265 | * be cancelled immediately. By default, <code>dispose()</code> <strong>does NOT unload its content</strong>, but | ||
| 266 | * you may set the <code>flushContent</code> parameter to <code>true</code> in order to flush/unload the <code>content</code> as well | ||
| 267 | * (in the case of ImageLoaders, SWFLoaders, and VideoLoaders, this will also destroy its ContentDisplay Sprite, removing it | ||
| 268 | * from the display list if necessary). When a loader is disposed, all of the listeners that were added through the | ||
| 269 | * <code>vars</code> object (like <code>{onComplete:completeHandler, onProgress:progressHandler}</code>) are removed. | ||
| 270 | * If you manually added listeners, though, you should remove those yourself. | ||
| 271 | * | ||
| 272 | * @param flushContent If <code>true</code>, the loader's <code>content</code> will be unloaded as well (<code>flushContent</code> is <code>false</code> by default). In the case of ImageLoaders, SWFLoaders, and VideoLoaders, their ContentDisplay will also be removed from the display list if necessary when <code>flushContent</code> is <code>true</code>. | ||
| 273 | * @see #unload() | ||
| 274 | **/ | ||
| 275 | public function dispose(flushContent:Boolean=false):void { | ||
| 276 | _dump((flushContent ? 3 : 2), LoaderStatus.DISPOSED); | ||
| 277 | } | ||
| 278 | |||
| 279 | /** | ||
| 280 | * Immediately prioritizes the loader inside any LoaderMax instances that contain it, | ||
| 281 | * forcing it to the top position in their queue and optionally calls <code>load()</code> | ||
| 282 | * immediately as well. If one of its parent LoaderMax instances is currently loading a | ||
| 283 | * different loader, that one will be temporarily cancelled. <br /><br /> | ||
| 284 | * | ||
| 285 | * By contrast, when <code>load()</code> is called, it doesn't change the loader's position/index | ||
| 286 | * in any LoaderMax queues. For example, if a LoaderMax is working on loading the first object in | ||
| 287 | * its queue, you can call load() on the 20th item and it will honor your request without | ||
| 288 | * changing its index in the queue. <code>prioritize()</code>, however, affects the position | ||
| 289 | * in the queue and optionally loads it immediately as well.<br /><br /> | ||
| 290 | * | ||
| 291 | * So even if your LoaderMax hasn't begun loading yet, you could <code>prioritize(false)</code> | ||
| 292 | * a loader and it will rise to the top of all LoaderMax instances to which it belongs, but not | ||
| 293 | * start loading yet. If the goal is to load something immediately, you can just use the | ||
| 294 | * <code>load()</code> method. | ||
| 295 | * | ||
| 296 | * @param loadNow If <code>true</code> (the default), the loader will start loading immediately (otherwise it is simply placed at the top the queue in any LoaderMax instances to which it belongs). | ||
| 297 | * @see #load() | ||
| 298 | **/ | ||
| 299 | public function prioritize(loadNow:Boolean=true):void { | ||
| 300 | dispatchEvent(new Event("prioritize")); | ||
| 301 | if (loadNow && _status != LoaderStatus.COMPLETED && _status != LoaderStatus.LOADING) { | ||
| 302 | load(false); | ||
| 303 | } | ||
| 304 | } | ||
| 305 | |||
| 306 | /** @inheritDoc **/ | ||
| 307 | override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void { | ||
| 308 | if (type == LoaderEvent.PROGRESS) { | ||
| 309 | _dispatchProgress = true; | ||
| 310 | } else if (type == LoaderEvent.CHILD_PROGRESS && this is LoaderMax) { | ||
| 311 | _dispatchChildProgress = true; | ||
| 312 | } | ||
| 313 | super.addEventListener(type, listener, useCapture, priority, useWeakReference); | ||
| 314 | } | ||
| 315 | |||
| 316 | /** @private **/ | ||
| 317 | protected function _calculateProgress():void { | ||
| 318 | //override in subclasses if necessary | ||
| 319 | } | ||
| 320 | |||
| 321 | /** | ||
| 322 | * Attempts loading just enough of the content to accurately determine the <code>bytesTotal</code> | ||
| 323 | * in order to improve the accuracy of the <code>progress</code> property. Once the | ||
| 324 | * <code>bytesTotal</code> has been determined or the <code>auditSize()</code> attempt fails due | ||
| 325 | * to an error (typically IO_ERROR or SECURITY_ERROR), the <code>auditedSize</code> property will be | ||
| 326 | * set to <code>true</code>. Auditing the size opens a URLStream that will be closed | ||
| 327 | * as soon as a response is received. | ||
| 328 | **/ | ||
| 329 | public function auditSize():void { | ||
| 330 | //override in subclasses | ||
| 331 | } | ||
| 332 | |||
| 333 | /** Returns information about the loader, like its type, its <code>name</code>, and its <code>url</code> (if it has one). **/ | ||
| 334 | override public function toString():String { | ||
| 335 | return _type + " '" + this.name + "'" + ((this is LoaderItem) ? " (" + (this as LoaderItem).url + ")" : ""); | ||
| 336 | } | ||
| 337 | |||
| 338 | //---- STATIC METHODS ------------------------------------------------------------------------------------ | ||
| 339 | |||
| 340 | /** @private **/ | ||
| 341 | protected static function _activateClass(type:String, loaderClass:Class, extensions:String):Boolean { | ||
| 342 | _types[type] = loaderClass; | ||
| 343 | var a:Array = extensions.split(","); | ||
| 344 | var i:int = a.length; | ||
| 345 | while (--i > -1) { | ||
| 346 | _extensions[a[i]] = loaderClass; | ||
| 347 | } | ||
| 348 | return true; | ||
| 349 | } | ||
| 350 | |||
| 351 | |||
| 352 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 353 | |||
| 354 | /** @private **/ | ||
| 355 | protected function _progressHandler(event:Event):void { | ||
| 356 | if (event is ProgressEvent) { | ||
| 357 | _cachedBytesLoaded = (event as ProgressEvent).bytesLoaded; | ||
| 358 | _cachedBytesTotal = (event as ProgressEvent).bytesTotal; | ||
| 359 | _auditedSize = true; | ||
| 360 | } | ||
| 361 | if (_dispatchProgress && _status == LoaderStatus.LOADING && _cachedBytesLoaded != _cachedBytesTotal) { | ||
| 362 | dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this)); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | |||
| 366 | /** @private **/ | ||
| 367 | protected function _completeHandler(event:Event=null):void { | ||
| 368 | _cachedBytesLoaded = _cachedBytesTotal; | ||
| 369 | if (_status != LoaderStatus.COMPLETED) { | ||
| 370 | dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this)); | ||
| 371 | _status = LoaderStatus.COMPLETED; | ||
| 372 | _time = getTimer() - _time; | ||
| 373 | } | ||
| 374 | dispatchEvent(new LoaderEvent(LoaderEvent.COMPLETE, this)); | ||
| 375 | if (this.autoDispose) { | ||
| 376 | dispose(); | ||
| 377 | } | ||
| 378 | } | ||
| 379 | |||
| 380 | /** @private **/ | ||
| 381 | protected function _errorHandler(event:Event):void { | ||
| 382 | var target:Object = (event is LoaderEvent && this.hasOwnProperty("getChildren")) ? event.target : this; | ||
| 383 | var text:String = (event as Object).text; | ||
| 384 | trace("Loading error on " + this.toString() + ": " + text); | ||
| 385 | if (event.type != LoaderEvent.ERROR && this.hasEventListener(event.type)) { | ||
| 386 | dispatchEvent(new LoaderEvent(event.type, target, text)); | ||
| 387 | } | ||
| 388 | if (this.hasEventListener(LoaderEvent.ERROR)) { | ||
| 389 | dispatchEvent(new LoaderEvent(LoaderEvent.ERROR, target, this.toString() + " > " + text)); | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | /** @private **/ | ||
| 394 | protected function _failHandler(event:Event):void { | ||
| 395 | _dump(0, LoaderStatus.FAILED); | ||
| 396 | _errorHandler(event); | ||
| 397 | dispatchEvent(new LoaderEvent(LoaderEvent.FAIL, ((event is LoaderEvent && this.hasOwnProperty("getChildren")) ? event.target : this), this.toString() + " > " + (event as Object).text)); | ||
| 398 | } | ||
| 399 | |||
| 400 | /** @private **/ | ||
| 401 | protected function _passThroughEvent(event:Event):void { | ||
| 402 | var type:String = event.type; | ||
| 403 | var target:Object = this; | ||
| 404 | if (this.hasOwnProperty("getChildren")) { | ||
| 405 | if (event is LoaderEvent) { | ||
| 406 | target = event.target; | ||
| 407 | } | ||
| 408 | if (type == "complete") { | ||
| 409 | type = "childComplete"; | ||
| 410 | } else if (type == "open") { | ||
| 411 | type = "childOpen"; | ||
| 412 | } else if (type == "cancel") { | ||
| 413 | type = "childCancel"; | ||
| 414 | } else if (type == "fail") { | ||
| 415 | type = "childFail"; | ||
| 416 | } | ||
| 417 | } | ||
| 418 | if (this.hasEventListener(type)) { | ||
| 419 | dispatchEvent(new LoaderEvent(type, target, (event.hasOwnProperty("text") ? (event as Object).text : ""))); | ||
| 420 | } | ||
| 421 | } | ||
| 422 | |||
| 423 | |||
| 424 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 425 | |||
| 426 | /** If a loader is paused, its progress will halt and any LoaderMax instances to which it belongs will either skip over it or stop when its position is reached in the queue (depending on whether or not the LoaderMax's <code>skipPaused</code> property is <code>true</code>). **/ | ||
| 427 | public function get paused():Boolean { | ||
| 428 | return Boolean(_status == LoaderStatus.PAUSED); | ||
| 429 | } | ||
| 430 | public function set paused(value:Boolean):void { | ||
| 431 | if (value && _status != LoaderStatus.PAUSED) { | ||
| 432 | _prePauseStatus = _status; | ||
| 433 | if (_status == LoaderStatus.LOADING) { | ||
| 434 | _dump(0, LoaderStatus.PAUSED); | ||
| 435 | } | ||
| 436 | _status == LoaderStatus.PAUSED; | ||
| 437 | |||
| 438 | } else if (!value && _status == LoaderStatus.PAUSED) { | ||
| 439 | if (_prePauseStatus == LoaderStatus.LOADING) { | ||
| 440 | load(false); //will change the _status for us inside load() | ||
| 441 | } else { | ||
| 442 | _status = _prePauseStatus || LoaderStatus.READY; | ||
| 443 | } | ||
| 444 | } | ||
| 445 | } | ||
| 446 | |||
| 447 | /** Integer code indicating the loader's status; options are <code>LoaderStatus.READY, LoaderStatus.LOADING, LoaderStatus.COMPLETE, LoaderStatus.PAUSED,</code> and <code>LoaderStatus.DISPOSED</code>. **/ | ||
| 448 | public function get status():int { | ||
| 449 | return _status; | ||
| 450 | } | ||
| 451 | |||
| 452 | /** Bytes loaded **/ | ||
| 453 | public function get bytesLoaded():uint { | ||
| 454 | if (_cacheIsDirty) { | ||
| 455 | _calculateProgress(); | ||
| 456 | } | ||
| 457 | return _cachedBytesLoaded; | ||
| 458 | } | ||
| 459 | |||
| 460 | /** Total bytes that are to be loaded by the loader. Initially, this value is set to the <code>estimatedBytes</code> if one was defined in the <code>vars</code> object via the constructor, or it defaults to <code>LoaderMax.defaultEstimatedBytes</code>. When the loader loads enough of the content to accurately determine the bytesTotal, it will do so automatically. **/ | ||
| 461 | public function get bytesTotal():uint { | ||
| 462 | if (_cacheIsDirty) { | ||
| 463 | _calculateProgress(); | ||
| 464 | } | ||
| 465 | return _cachedBytesTotal; | ||
| 466 | } | ||
| 467 | |||
| 468 | /** A value between 0 and 1 indicating the overall progress of the loader. When nothing has loaded, it will be 0; when it is halfway loaded, <code>progress</code> will be 0.5, and when it is fully loaded it will be 1. **/ | ||
| 469 | public function get progress():Number { | ||
| 470 | return (this.bytesTotal != 0) ? _cachedBytesLoaded / _cachedBytesTotal : (_status == LoaderStatus.COMPLETED) ? 1 : 0; | ||
| 471 | } | ||
| 472 | |||
| 473 | /** @private Every loader is associated with a root-level LoaderMax which will be the _globalQueue unless the loader had a <code>requireWithRoot</code> value passed into the constructor via the <code>vars</code> parameter. This enables us to chain things properly in subloaded swfs if, for example, a subloaded swf has LoaderMax instances of its own and we want the SWFLoader to accurately report its loading status based not only on the subloaded swf, but also the subloaded swf's LoaderMax instances. **/ | ||
| 474 | public function get rootLoader():LoaderMax { | ||
| 475 | return _rootLoader; | ||
| 476 | } | ||
| 477 | |||
| 478 | /** | ||
| 479 | * The content that was loaded by the loader which varies by the type of loader: | ||
| 480 | * <ul> | ||
| 481 | * <li><strong> ImageLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the ImageLoader's <code>rawContent</code> (a <code>flash.display.Bitmap</code> unless script access was denied in which case <code>rawContent</code> will be a <code>flash.display.Loader</code> to avoid security errors). For Flex users, you can set <code>LoaderMax.defaultContentDisplay</code> to <code>FlexContentDisplay</code> in which case ImageLoaders, SWFLoaders, and VideoLoaders will return a <code>com.greensock.loading.display.FlexContentDisplay</code> instance instead.</li> | ||
| 482 | * <li><strong> SWFLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the SWFLoader's <code>rawContent</code> (the swf's <code>root</code> DisplayObject unless script access was denied in which case <code>rawContent</code> will be a <code>flash.display.Loader</code> to avoid security errors). For Flex users, you can set <code>LoaderMax.defaultContentDisplay</code> to <code>FlexContentDisplay</code> in which case ImageLoaders, SWFLoaders, and VideoLoaders will return a <code>com.greensock.loading.display.FlexContentDisplay</code> instance instead.</li> | ||
| 483 | * <li><strong> VideoLoader </strong> - A <code>com.greensock.loading.display.ContentDisplay</code> (a Sprite) which contains the VideoLoader's <code>rawContent</code> (a Video object to which the NetStream was attached). For Flex users, you can set <code>LoaderMax.defaultContentDisplay</code> to <code>FlexContentDisplay</code> in which case ImageLoaders, SWFLoaders, and VideoLoaders will return a <code>com.greensock.loading.display.FlexContentDisplay</code> instance instead.</li> | ||
| 484 | * <li><strong> XMLLoader </strong> - XML</li> | ||
| 485 | * <li><strong> DataLoader </strong> | ||
| 486 | * <ul> | ||
| 487 | * <li><code>String</code> if the DataLoader's <code>format</code> vars property is <code>"text"</code> (the default).</li> | ||
| 488 | * <li><code>flash.utils.ByteArray</code> if the DataLoader's <code>format</code> vars property is <code>"binary"</code>.</li> | ||
| 489 | * <li><code>flash.net.URLVariables</code> if the DataLoader's <code>format</code> vars property is <code>"variables"</code>.</li> | ||
| 490 | * </ul></li> | ||
| 491 | * <li><strong> CSSLoader </strong> - <code>flash.text.StyleSheet</code></li> | ||
| 492 | * <li><strong> MP3Loader </strong> - <code>flash.media.Sound</code></li> | ||
| 493 | * <li><strong> LoaderMax </strong> - an array containing the content objects from each of its child loaders.</li> | ||
| 494 | * </ul> | ||
| 495 | **/ | ||
| 496 | public function get content():* { | ||
| 497 | return _content; | ||
| 498 | } | ||
| 499 | |||
| 500 | /** | ||
| 501 | * Indicates whether or not the loader's <code>bytesTotal</code> value has been set by any of the following: | ||
| 502 | * <ul> | ||
| 503 | * <li>Defining an <code>estimatedBytes</code> in the <code>vars</code> object passed to the constructor</li> | ||
| 504 | * <li>Calling <code>auditSize()</code> and getting a response (an error is also considered a response)</li> | ||
| 505 | * <li>When a LoaderMax instance begins loading, it will automatically force a call to <code>auditSize()</code> for any of its children that don't have an <code>estimatedBytes</code> defined. You can disable this behavior by passing <code>auditSize:false</code> through the constructor's <code>vars</code> object.</li> | ||
| 506 | * </ul> | ||
| 507 | **/ | ||
| 508 | public function get auditedSize():Boolean { | ||
| 509 | return _auditedSize; | ||
| 510 | } | ||
| 511 | |||
| 512 | /** | ||
| 513 | * The number of seconds that elapsed between when the loader began and when it either completed, failed, | ||
| 514 | * or was canceled. You may check a loader's <code>loadTime</code> anytime, not just after it completes. For | ||
| 515 | * example, you could access this value in an onProgress handler and you'd see it steadily increase as the loader | ||
| 516 | * loads and then when it completes, <code>loadTime</code> will stop increasing. LoaderMax instances ignore | ||
| 517 | * any pauses when calculating this value, so if a LoaderMax begins loading and after 1 second it gets paused, | ||
| 518 | * and then 10 seconds later it resumes and takes an additional 14 seconds to complete, its <code>loadTime</code> | ||
| 519 | * would be 15, <strong>not</strong> 25. | ||
| 520 | **/ | ||
| 521 | public function get loadTime():Number { | ||
| 522 | if (_status == LoaderStatus.READY) { | ||
| 523 | return 0; | ||
| 524 | } else if (_status == LoaderStatus.LOADING) { | ||
| 525 | return (getTimer() - _time) / 1000; | ||
| 526 | } else { | ||
| 527 | return _time / 1000; | ||
| 528 | } | ||
| 529 | } | ||
| 530 | |||
| 531 | } | ||
| 532 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.3 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.core { | ||
| 8 | import com.greensock.events.LoaderEvent; | ||
| 9 | import com.greensock.loading.LoaderStatus; | ||
| 10 | |||
| 11 | import flash.events.Event; | ||
| 12 | import flash.events.ProgressEvent; | ||
| 13 | import flash.net.URLRequest; | ||
| 14 | import flash.net.URLStream; | ||
| 15 | |||
| 16 | /** Dispatched when the loader experiences an IO_ERROR while loading or auditing its size. **/ | ||
| 17 | [Event(name="ioError", type="com.greensock.events.LoaderEvent")] | ||
| 18 | /** | ||
| 19 | * Serves as the base class for all individual loaders (not LoaderMax) like <code>ImageLoader, | ||
| 20 | * XMLLoader, SWFLoader, MP3Loader</code>, etc. There is no reason to use this class on its own. | ||
| 21 | * Please see the documentation for the other classes. | ||
| 22 | * <br /><br /> | ||
| 23 | * | ||
| 24 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 25 | * | ||
| 26 | * @author Jack Doyle, jack@greensock.com | ||
| 27 | */ | ||
| 28 | public class LoaderItem extends LoaderCore { | ||
| 29 | /** @private **/ | ||
| 30 | protected static var _cacheID:uint = uint(Math.random() * 100000000) * int(Math.random() * 1000); | ||
| 31 | |||
| 32 | /** @private **/ | ||
| 33 | protected var _url:String; | ||
| 34 | /** @private **/ | ||
| 35 | protected var _request:URLRequest; | ||
| 36 | /** @private **/ | ||
| 37 | protected var _scriptAccessDenied:Boolean; | ||
| 38 | /** @private used in auditSize() just to preload enough of the file to determine bytesTotal. **/ | ||
| 39 | protected var _auditStream:URLStream; | ||
| 40 | /** @private For certain types of loaders like SWFLoader and XMLLoader where there may be nested loaders found, it's better to prioritize the estimatedBytes if one is defined. Otherwise, the file size will be used which may be MUCH smaller than all the assets inside of it (like an XML file with a bunch of VideoLoaders).**/ | ||
| 41 | protected var _preferEstimatedBytesInAudit:Boolean; | ||
| 42 | /** @private **/ | ||
| 43 | protected var _httpStatus:int; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * Constructor | ||
| 47 | * | ||
| 48 | * @param urlOrRequest The url (<code>String</code>) or <code>URLRequest</code> from which the loader should get its content | ||
| 49 | * @param vars An object containing optional parameters like <code>estimatedBytes, name, autoDispose, onComplete, onProgress, onError</code>, etc. For example, <code>{estimatedBytes:2400, name:"myImage1", onComplete:completeHandler}</code>. | ||
| 50 | */ | ||
| 51 | public function LoaderItem(urlOrRequest:*, vars:Object=null) { | ||
| 52 | super(vars); | ||
| 53 | _request = (urlOrRequest is URLRequest) ? urlOrRequest as URLRequest : new URLRequest(urlOrRequest); | ||
| 54 | _url = _request.url; | ||
| 55 | } | ||
| 56 | |||
| 57 | /** @private **/ | ||
| 58 | protected function _prepRequest():void { | ||
| 59 | _scriptAccessDenied = false; | ||
| 60 | _httpStatus = 0; | ||
| 61 | _closeStream(); | ||
| 62 | if (this.vars.noCache && (!_isLocal || _url.substr(0, 4) == "http")) { | ||
| 63 | _request.url = _url + ((_url.indexOf("?") == -1) ? "?" : "&") + "cacheBusterID=" + (_cacheID++); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | /** @private scrubLevel: 0 = cancel, 1 = unload, 2 = dispose, 3 = flush **/ | ||
| 68 | override protected function _dump(scrubLevel:int=0, newStatus:int=0, suppressEvents:Boolean=false):void { | ||
| 69 | _closeStream(); | ||
| 70 | super._dump(scrubLevel, newStatus, suppressEvents); | ||
| 71 | } | ||
| 72 | |||
| 73 | /** @inheritDoc **/ | ||
| 74 | override public function auditSize():void { | ||
| 75 | if (_auditStream == null) { | ||
| 76 | _auditStream = new URLStream(); | ||
| 77 | _auditStream.addEventListener(ProgressEvent.PROGRESS, _auditStreamHandler, false, 0, true); | ||
| 78 | _auditStream.addEventListener(Event.COMPLETE, _auditStreamHandler, false, 0, true); | ||
| 79 | _auditStream.addEventListener("ioError", _auditStreamHandler, false, 0, true); | ||
| 80 | _auditStream.addEventListener("securityError", _auditStreamHandler, false, 0, true); | ||
| 81 | _auditStream.load(_request); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | /** @private **/ | ||
| 86 | protected function _closeStream():void { | ||
| 87 | if (_auditStream != null) { | ||
| 88 | _auditStream.removeEventListener(ProgressEvent.PROGRESS, _auditStreamHandler); | ||
| 89 | _auditStream.removeEventListener(Event.COMPLETE, _auditStreamHandler); | ||
| 90 | _auditStream.removeEventListener("ioError", _auditStreamHandler); | ||
| 91 | _auditStream.removeEventListener("securityError", _auditStreamHandler); | ||
| 92 | try { | ||
| 93 | _auditStream.close(); | ||
| 94 | } catch (error:Error) { | ||
| 95 | |||
| 96 | } | ||
| 97 | _auditStream = null; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | //---- EVENT HANDLERS ------------------------------------------------------------------------------------ | ||
| 102 | |||
| 103 | /** @private **/ | ||
| 104 | protected function _auditStreamHandler(event:Event):void { | ||
| 105 | if (event is ProgressEvent) { | ||
| 106 | _cachedBytesTotal = (event as ProgressEvent).bytesTotal; | ||
| 107 | if (_preferEstimatedBytesInAudit && uint(this.vars.estimatedBytes) > _cachedBytesTotal) { | ||
| 108 | _cachedBytesTotal = uint(this.vars.estimatedBytes); | ||
| 109 | } | ||
| 110 | } else if (event.type == "ioError" || event.type == "securityError") { | ||
| 111 | if (this.vars.alternateURL != undefined && this.vars.alternateURL != "" && _url != this.vars.alternateURL) { | ||
| 112 | _url = _request.url = this.vars.alternateURL; | ||
| 113 | _auditStream.load(_request); | ||
| 114 | _errorHandler(event); | ||
| 115 | return; | ||
| 116 | } else { | ||
| 117 | //note: a CANCEL event won't be dispatched because technically the loader wasn't officially loading - we were only briefly checking the bytesTotal with a NetStream. | ||
| 118 | super._failHandler(event); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | _auditedSize = true; | ||
| 122 | _closeStream(); | ||
| 123 | dispatchEvent(new Event("auditedSize")); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** @private **/ | ||
| 127 | override protected function _failHandler(event:Event):void { | ||
| 128 | if (this.vars.alternateURL != undefined && this.vars.alternateURL != "" && _url != this.vars.alternateURL) { | ||
| 129 | this.url = this.vars.alternateURL; //also calls _load() | ||
| 130 | _errorHandler(event); | ||
| 131 | } else { | ||
| 132 | super._failHandler(event); | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | |||
| 137 | /** @private **/ | ||
| 138 | protected function _httpStatusHandler(event:Event):void { | ||
| 139 | _httpStatus = (event as Object).status; | ||
| 140 | dispatchEvent(new LoaderEvent(LoaderEvent.HTTP_STATUS, this)); | ||
| 141 | } | ||
| 142 | |||
| 143 | |||
| 144 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 145 | |||
| 146 | /** The url from which the loader should get its content. **/ | ||
| 147 | public function get url():String { | ||
| 148 | return _url; | ||
| 149 | } | ||
| 150 | public function set url(value:String):void { | ||
| 151 | if (_url != value) { | ||
| 152 | _url = _request.url = value; | ||
| 153 | var isLoading:Boolean = Boolean(_status == LoaderStatus.LOADING); | ||
| 154 | _dump(0, LoaderStatus.READY, true); | ||
| 155 | if (isLoading) { | ||
| 156 | _load(); | ||
| 157 | } | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | /** The <code>URLRequest</code> associated with the loader. **/ | ||
| 162 | public function get request():URLRequest { | ||
| 163 | return _request; | ||
| 164 | } | ||
| 165 | |||
| 166 | /** The httpStatus code of the loader. You may listen for <code>LoaderEvent.HTTP_STATUS</code> events on certain types of loaders to be notified when it changes, but in some environments the Flash player cannot sense httpStatus codes in which case the value will remain <code>0</code>. **/ | ||
| 167 | public function get httpStatus():int { | ||
| 168 | return _httpStatus; | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * If the loaded content is denied script access (because of security sandbox restrictions, | ||
| 173 | * a missing crossdomain.xml file, etc.), <code>scriptAccessDenied</code> will be set to <code>true</code>. | ||
| 174 | * In the case of loaded images or swf files, this means that you should not attempt to perform | ||
| 175 | * BitmapData operations on the content. An image's <code>smoothing</code> property cannot be set | ||
| 176 | * to <code>true</code> either. Even if script access is denied for particular content, LoaderMax will still | ||
| 177 | * attempt to load it. | ||
| 178 | **/ | ||
| 179 | public function get scriptAccessDenied():Boolean { | ||
| 180 | return _scriptAccessDenied; | ||
| 181 | } | ||
| 182 | |||
| 183 | } | ||
| 184 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data { | ||
| 8 | import com.greensock.loading.data.core.LoaderItemVars; | ||
| 9 | import flash.display.DisplayObject; | ||
| 10 | /** | ||
| 11 | * Can be used instead of a generic object to define the <code>vars</code> parameter of a CSSLoader's constructor. <br /><br /> | ||
| 12 | * | ||
| 13 | * There are 2 primary benefits of using a CSSLoaderVars instance to define your CSSLoader variables: | ||
| 14 | * <ol> | ||
| 15 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in CSSLoader</li> | ||
| 16 | * <li> It enables strict data typing for improved debugging (ensuring, for example, that you don't define a Boolean value for <code>onComplete</code> where a Function is expected).</li> | ||
| 17 | * </ol> | ||
| 18 | * | ||
| 19 | * <strong>USAGE:</strong><br /><br /> | ||
| 20 | * | ||
| 21 | * Instead of <code>new CSSLoader("styles.css", {name:"css", estimatedBytes:1500, onComplete:completeHandler, onProgress:progressHandler})</code>, | ||
| 22 | * you could use this utility like:<br /><br /><code> | ||
| 23 | * | ||
| 24 | * var vars:CSSLoaderVars = new CSSLoaderVars();<br /> | ||
| 25 | * vars.name = "css";<br /> | ||
| 26 | * vars.estimatedBytes = 1500;<br /> | ||
| 27 | * vars.onComplete = completeHandler;<br /> | ||
| 28 | * vars.onProgress = progressHandler;<br /> | ||
| 29 | * var loader:CSSLoader = new CSSLoader("styles.css", vars);<br /><br /></code> | ||
| 30 | * | ||
| 31 | * Some of the most common properties can be defined directly in the constructor like this:<br /><br /><code> | ||
| 32 | * | ||
| 33 | * var loader:CSSLoader = new CSSLoader("styles.css", new CSSLoaderVars("css", 1500, completeHandler, progressHandler) );<br /><br /></code> | ||
| 34 | * | ||
| 35 | * <strong>NOTE:</strong> Using CSSLoaderVars is completely optional. If you prefer the shorter synatax with the generic Object, feel | ||
| 36 | * free to use it. The purpose of this class is simply to enable code hinting and to allow for strict data typing. <br /><br /> | ||
| 37 | * | ||
| 38 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 39 | * | ||
| 40 | * @author Jack Doyle, jack@greensock.com | ||
| 41 | */ | ||
| 42 | dynamic public class CSSLoaderVars extends LoaderItemVars { | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Constructor | ||
| 46 | * | ||
| 47 | * @param name A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". | ||
| 48 | * @param estimatedBytes Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). | ||
| 49 | * @param onComplete A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 50 | * @param onProgress A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. | ||
| 51 | * @param onFail A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 52 | * @param noCache If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). | ||
| 53 | * @param alternateURL If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example). | ||
| 54 | * @param requireWithRoot LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. | ||
| 55 | */ | ||
| 56 | public function CSSLoaderVars(name:String="", | ||
| 57 | estimatedBytes:uint=0, | ||
| 58 | onComplete:Function=null, | ||
| 59 | onProgress:Function=null, | ||
| 60 | onFail:Function=null, | ||
| 61 | noCache:Boolean=false, | ||
| 62 | alternateURL:String="", | ||
| 63 | requireWithRoot:DisplayObject=null) { | ||
| 64 | super(name, estimatedBytes, onComplete, onProgress, onFail, noCache, alternateURL, requireWithRoot); | ||
| 65 | } | ||
| 66 | |||
| 67 | /** Clones the object. **/ | ||
| 68 | public function clone():CSSLoaderVars { | ||
| 69 | return _cloneProps(new CSSLoaderVars()) as CSSLoaderVars; | ||
| 70 | } | ||
| 71 | |||
| 72 | } | ||
| 73 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data { | ||
| 8 | import com.greensock.loading.core.LoaderCore; | ||
| 9 | import com.greensock.loading.data.core.LoaderItemVars; | ||
| 10 | |||
| 11 | import flash.display.DisplayObject; | ||
| 12 | /** | ||
| 13 | * Can be used instead of a generic object to define the <code>vars</code> parameter of a DataLoader's constructor. <br /><br /> | ||
| 14 | * | ||
| 15 | * There are 2 primary benefits of using a DataLoaderVars instance to define your DataLoader variables: | ||
| 16 | * <ol> | ||
| 17 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in DataLoader</li> | ||
| 18 | * <li> It enables strict data typing for improved debugging (ensuring, for example, that you don't define a Boolean value for <code>onComplete</code> where a Function is expected).</li> | ||
| 19 | * </ol> | ||
| 20 | * | ||
| 21 | * <strong>USAGE:</strong><br /><br /> | ||
| 22 | * | ||
| 23 | * Instead of <code>new DataLoader("getData.php", {name:"myData", estimatedBytes:1500, format:"text", onComplete:completeHandler, onProgress:progressHandler})</code>, | ||
| 24 | * you could use this utility like:<br /><br /><code> | ||
| 25 | * | ||
| 26 | * var vars:DataLoaderVars = new DataLoaderVars();<br /> | ||
| 27 | * vars.name = "myData";<br /> | ||
| 28 | * vars.estimatedBytes = 1500;<br /> | ||
| 29 | * vars.format = "text";<br /> | ||
| 30 | * vars.onComplete = completeHandler;<br /> | ||
| 31 | * vars.onProgress = progressHandler;<br /> | ||
| 32 | * var loader:DataLoader = new DataLoader("getData.php", vars);<br /><br /></code> | ||
| 33 | * | ||
| 34 | * Some of the most common properties can be defined directly in the constructor like this:<br /><br /><code> | ||
| 35 | * | ||
| 36 | * var loader:DataLoader = new DataLoader("getData.php", new DataLoaderVars("myData", 1500, "text", completeHandler, progressHandler) );<br /><br /></code> | ||
| 37 | * | ||
| 38 | * <strong>NOTE:</strong> Using DataLoaderVars is completely optional. If you prefer the shorter synatax with the generic Object, feel | ||
| 39 | * free to use it. The purpose of this class is simply to enable code hinting and to allow for strict data typing. <br /><br /> | ||
| 40 | * | ||
| 41 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 42 | * | ||
| 43 | * @author Jack Doyle, jack@greensock.com | ||
| 44 | */ | ||
| 45 | dynamic public class DataLoaderVars extends LoaderItemVars { | ||
| 46 | /** @private **/ | ||
| 47 | private static var _vars:Array = ["format"]; | ||
| 48 | |||
| 49 | /** Controls whether the downloaded data is received as text (<code>"text"</code>), raw binary data (<code>"binary"</code>), or URL-encoded variables (<code>"variables"</code>). **/ | ||
| 50 | public var format:String; | ||
| 51 | |||
| 52 | |||
| 53 | /** | ||
| 54 | * Constructor | ||
| 55 | * | ||
| 56 | * @param name A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". | ||
| 57 | * @param estimatedBytes Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). | ||
| 58 | * @param format Controls whether the downloaded data is received as text (<code>"text"</code>), raw binary data (<code>"binary"</code>), or URL-encoded variables (<code>"variables"</code>). | ||
| 59 | * @param onComplete A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 60 | * @param onProgress A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. | ||
| 61 | * @param onFail A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 62 | * @param noCache If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). | ||
| 63 | * @param alternateURL If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example). | ||
| 64 | * @param requireWithRoot LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. | ||
| 65 | */ | ||
| 66 | public function DataLoaderVars(name:String="", | ||
| 67 | estimatedBytes:uint=0, | ||
| 68 | format:String="text", | ||
| 69 | onComplete:Function=null, | ||
| 70 | onProgress:Function=null, | ||
| 71 | onFail:Function=null, | ||
| 72 | noCache:Boolean=false, | ||
| 73 | alternateURL:String="", | ||
| 74 | requireWithRoot:DisplayObject=null) { | ||
| 75 | super(name, estimatedBytes, onComplete, onProgress, onFail, noCache, alternateURL, requireWithRoot); | ||
| 76 | _props = _props.concat(_vars); | ||
| 77 | this.format = format; | ||
| 78 | } | ||
| 79 | |||
| 80 | /** Clones the object. **/ | ||
| 81 | public function clone():DataLoaderVars { | ||
| 82 | return _cloneProps(new DataLoaderVars()) as DataLoaderVars; | ||
| 83 | } | ||
| 84 | |||
| 85 | } | ||
| 86 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data { | ||
| 8 | import com.greensock.loading.data.core.DisplayObjectLoaderVars; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | import flash.display.DisplayObjectContainer; | ||
| 12 | import flash.system.LoaderContext; | ||
| 13 | /** | ||
| 14 | * Can be used instead of a generic object to define the <code>vars</code> parameter of an ImageLoader's constructor. <br /><br /> | ||
| 15 | * | ||
| 16 | * There are 2 primary benefits of using a ImageLoaderVars instance to define your ImageLoader variables: | ||
| 17 | * <ol> | ||
| 18 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in ImageLoader</li> | ||
| 19 | * <li> It enables strict data typing for improved debugging (ensuring, for example, that you don't define a Boolean value for <code>onComplete</code> where a Function is expected).</li> | ||
| 20 | * </ol> | ||
| 21 | * | ||
| 22 | * <strong>USAGE:</strong><br /><br /> | ||
| 23 | * | ||
| 24 | * Instead of <code>new ImageLoader("photo1.jpg", {name:"photo1", estimatedBytes:11500, container:this, width:200, height:100, onComplete:completeHandler, onProgress:progressHandler})</code>, | ||
| 25 | * you could use this utility like:<br /><br /><code> | ||
| 26 | * | ||
| 27 | * var vars:ImageLoaderVars = new ImageLoaderVars();<br /> | ||
| 28 | * vars.name = "photo1";<br /> | ||
| 29 | * vars.estimatedBytes = 11500;<br /> | ||
| 30 | * vars.container = this;<br /> | ||
| 31 | * vars.width = 200;<br /> | ||
| 32 | * vars.height = 100;<br /> | ||
| 33 | * vars.onComplete = completeHandler;<br /> | ||
| 34 | * vars.onProgress = progressHandler;<br /> | ||
| 35 | * var loader:ImageLoader = new ImageLoader("photo1.jpg", vars);<br /><br /></code> | ||
| 36 | * | ||
| 37 | * Some of the most common properties can be defined directly in the constructor like this:<br /><br /><code> | ||
| 38 | * | ||
| 39 | * var loader:ImageLoader = new ImageLoader("photo1.jpg", new ImageLoaderVars("photo1", 11500, this, 200, 100, completeHandler, progressHandler) );<br /><br /></code> | ||
| 40 | * | ||
| 41 | * <strong>NOTE:</strong> Using ImageLoaderVars is completely optional. If you prefer the shorter synatax with the generic Object, feel | ||
| 42 | * free to use it. The purpose of this class is simply to enable code hinting and to allow for strict data typing. <br /><br /> | ||
| 43 | * | ||
| 44 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 45 | * | ||
| 46 | * @author Jack Doyle, jack@greensock.com | ||
| 47 | */ | ||
| 48 | dynamic public class ImageLoaderVars extends DisplayObjectLoaderVars { | ||
| 49 | /** @private **/ | ||
| 50 | private static var _vars:Array = ["smoothing","context"]; | ||
| 51 | |||
| 52 | /** When <code>smoothing</code> is <code>true</code> (the default), smoothing will be enabled for the image which typically leads to much better scaling results (otherwise the image can look crunchy/jagged). If your image is loaded from another domain where the appropriate crossdomain.xml file doesn't grant permission, Flash will not allow smoothing to be enabled (it's a security restriction). **/ | ||
| 53 | public var smoothing:Boolean = true; | ||
| 54 | /** To control whether or not a policy file is checked (which is required if you're loading an image from another domain and you want to use it in BitmapData operations), define a <code>LoaderContext</code> object. By default, the policy file <strong>will</strong> be checked when running remotely, so make sure the appropriate crossdomain.xml file is in place. See Adobe's <code>LoaderContext</code> documentation for details and precautions. **/ | ||
| 55 | public var context:LoaderContext; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Constructor | ||
| 59 | * | ||
| 60 | * @param name A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". | ||
| 61 | * @param estimatedBytes Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). | ||
| 62 | * @param container A DisplayObjectContainer into which the <code>ContentDisplay</code> Sprite should be added immediately. | ||
| 63 | * @param width Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY). | ||
| 64 | * @param height Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY). | ||
| 65 | * @param scaleMode When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded image will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer):<code>"stretch" | "proportionalInside" | "proportionalOutside" | "widthOnly" | "heightOnly" | "none"</code> | ||
| 66 | * @param onComplete A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 67 | * @param onProgress A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. | ||
| 68 | * @param onFail A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 69 | * @param noCache If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). | ||
| 70 | * @param alternateURL If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example). | ||
| 71 | * @param requireWithRoot LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. | ||
| 72 | */ | ||
| 73 | public function ImageLoaderVars(name:String="", | ||
| 74 | estimatedBytes:uint=0, | ||
| 75 | container:DisplayObjectContainer=null, | ||
| 76 | width:Number=NaN, | ||
| 77 | height:Number=NaN, | ||
| 78 | scaleMode:String="stretch", | ||
| 79 | onComplete:Function=null, | ||
| 80 | onProgress:Function=null, | ||
| 81 | onFail:Function=null, | ||
| 82 | noCache:Boolean=false, | ||
| 83 | alternateURL:String="", | ||
| 84 | requireWithRoot:DisplayObject=null) { | ||
| 85 | super(name, estimatedBytes, container, width, height, scaleMode, onComplete, onProgress, onFail, noCache, alternateURL, requireWithRoot); | ||
| 86 | _props = _props.concat(_vars); | ||
| 87 | } | ||
| 88 | |||
| 89 | /** Clones the object. **/ | ||
| 90 | public function clone():ImageLoaderVars { | ||
| 91 | return _cloneProps(new ImageLoaderVars()) as ImageLoaderVars; | ||
| 92 | } | ||
| 93 | |||
| 94 | } | ||
| 95 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data { | ||
| 8 | import com.greensock.loading.core.LoaderCore; | ||
| 9 | import com.greensock.loading.data.core.LoaderCoreVars; | ||
| 10 | import com.greensock.loading.LoaderMax; | ||
| 11 | |||
| 12 | import flash.display.DisplayObject; | ||
| 13 | /** | ||
| 14 | * Can be used instead of a generic object to define the <code>vars</code> parameter of a LoaderMax's constructor. <br /><br /> | ||
| 15 | * | ||
| 16 | * There are 2 primary benefits of using a LoaderMaxVars instance to define your LoaderMax variables: | ||
| 17 | * <ol> | ||
| 18 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in LoaderMax</li> | ||
| 19 | * <li> It enables strict data typing for improved debugging (ensuring, for example, that you don't define a Boolean value for <code>onComplete</code> where a Function is expected).</li> | ||
| 20 | * </ol> | ||
| 21 | * | ||
| 22 | * <strong>USAGE:</strong><br /><br /> | ||
| 23 | * | ||
| 24 | * Instead of <code>new LoaderMax({name:"mainQueue", onComplete:completeHandler, onProgress:progressHandler})</code>, you could use this utility like:<br /><br /><code> | ||
| 25 | * | ||
| 26 | * var vars:LoaderMaxVars = new LoaderMaxVars();<br /> | ||
| 27 | * vars.name = "mainQueue";<br /> | ||
| 28 | * vars.onComplete = completeHandler;<br /> | ||
| 29 | * vars.onProgress = progressHandler;<br /> | ||
| 30 | * var queue:LoaderMax = new LoaderMax(vars);<br /><br /></code> | ||
| 31 | * | ||
| 32 | * Some of the most common properties can be defined directly in the constructor like this:<br /><br /><code> | ||
| 33 | * | ||
| 34 | * var queue:LoaderMax = new LoaderMax( new LoaderMaxVars("mainQueue", completeHandler, progressHandler) );<br /><br /></code> | ||
| 35 | * | ||
| 36 | * <strong>NOTE:</strong> Using LoaderMaxVars is completely optional. If you prefer the shorter synatax with the generic Object, feel | ||
| 37 | * free to use it. The purpose of this class is simply to enable code hinting and to allow for strict data typing. <br /><br /> | ||
| 38 | * | ||
| 39 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 40 | * | ||
| 41 | * @author Jack Doyle, jack@greensock.com | ||
| 42 | */ | ||
| 43 | dynamic public class LoaderMaxVars extends LoaderCoreVars { | ||
| 44 | /** @private **/ | ||
| 45 | private static var _vars:Array = ["auditSize", | ||
| 46 | "maxConnections", | ||
| 47 | "skipFailed", | ||
| 48 | "skipPaused", | ||
| 49 | "loaders", | ||
| 50 | "onChildOpen", | ||
| 51 | "onChildProgress", | ||
| 52 | "onChildComplete", | ||
| 53 | "onChildCancel", | ||
| 54 | "onChildFail", | ||
| 55 | "onScriptAccessDenied"]; | ||
| 56 | |||
| 57 | /** By default, when the LoaderMax begins to load it quickly loops through its children and if it finds any that don't have an <code>estimatedBytes</code> defined, it will briefly open a URLStream in order to attempt to determine its <code>bytesTotal</code>, immediately closing the URLStream once the value has been determined. This causes a brief delay initially, but greatly improves the accuracy of the <code>progress</code> and <code>bytesTotal</code> values. Set <code>auditSize</code> to <code>false</code> to prevent the LoaderMax from auditing its childrens' size (it is <code>true</code> by default). For maximum performance, it is best to define an <code>estimatedBytes</code> value for as many loaders as possible to avoid the delay caused by audits. When the LoaderMax audits an XMLLoader, it cannot recognize loaders that will be created from the XML data nor can it recognize loaders inside subloaded swf files from a SWFLoader (it would take far too long to load sufficient data for that - audits should be as fast as possible). If you do not set an appropriate <code>estimatedSize</code> for XMLLoaders or SWFLoaders that contain LoaderMax loaders, you'll notice that the parent LoaderMax's <code>progress</code> and <code>bytesTotal</code> change when the nested loaders are recognized (this is normal). To control the default <code>auditSize</code> value, use the static <code>LoaderMax.defaultAuditSize</code> property. **/ | ||
| 58 | public var auditSize:Boolean; | ||
| 59 | /** Maximum number of simultaneous connections that should be used while loading the LoaderMax queue. A higher number will generally result in faster overall load times for the group. The default is 2. This value is instance-based, not system-wide, so if you have two LoaderMax instances that both have a <code>maxConnections</code> value of 3 and they are both loading, there could be up to 6 connections at a time total. Sometimes there are limits imposed by the Flash Player itself or the browser or the user's system, but LoaderMax will do its best to honor the <code>maxConnections</code> you define. **/ | ||
| 60 | public var maxConnections:uint; | ||
| 61 | /** If <code>skipFailed</code> is <code>true</code> (the default), any failed loaders in the queue will be skipped. Otherwise, the LoaderMax will stop when it hits a failed loader and the LoaderMax's status will become <code>LoaderStatus.FAILED</code>. **/ | ||
| 62 | public var skipFailed:Boolean; | ||
| 63 | /** If <code>skipPaused</code> is <code>true</code> (the default), any paused loaders in the queue will be skipped. Otherwise, the LoaderMax will stop when it hits a paused loader and the LoaderMax's status will become <code>LoaderStatus.FAILED</code>. **/ | ||
| 64 | public var skipPaused:Boolean; | ||
| 65 | /** An array of loaders (ImageLoaders, SWFLoaders, XMLLoaders, MP3Loaders, other LoaderMax instances, etc.) that should be immediately inserted into the LoaderMax. **/ | ||
| 66 | public var loaders:Array; | ||
| 67 | |||
| 68 | /** A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time one of the loader's children (or any descendant) begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 69 | public var onChildOpen:Function; | ||
| 70 | /** A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time one of the loader's children (or any descendant) dispatches a <code>PROGRESS</code> event. To listen for changes in the LoaderMax's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the LoaderMax, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 71 | public var onChildProgress:Function; | ||
| 72 | /** A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time one of the loader's children (or any descendant) finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 73 | public var onChildComplete:Function; | ||
| 74 | /** A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on one of the loader's children (or any descendant) due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 75 | public var onChildCancel:Function; | ||
| 76 | /** A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time one of the loader's children (or any descendant) fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 77 | public var onChildFail:Function; | ||
| 78 | /** A handler function for <code>LoaderEvent.SCRIPT_ACCESS_DENIED</code> events which are dispatched when one of the LoaderMax's children (or any descendant) is loaded from another domain and no crossdomain.xml is in place to grant full script access for things like smoothing or BitmapData manipulation. Make sure your function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).**/ | ||
| 79 | public var onScriptAccessDenied:Function; | ||
| 80 | |||
| 81 | |||
| 82 | /** | ||
| 83 | * Constructor | ||
| 84 | * | ||
| 85 | */ | ||
| 86 | public function LoaderMaxVars(name:String="", | ||
| 87 | onComplete:Function=null, | ||
| 88 | onProgress:Function=null, | ||
| 89 | onFail:Function=null, | ||
| 90 | maxConnections:uint=2, | ||
| 91 | auditSize:Boolean=true, | ||
| 92 | requireWithRoot:DisplayObject=null, | ||
| 93 | skipFailed:Boolean=true, | ||
| 94 | skipPaused:Boolean=true) { | ||
| 95 | super(name, onComplete, onProgress, onFail, requireWithRoot); | ||
| 96 | _props = _props.concat(_vars); | ||
| 97 | this.maxConnections = maxConnections; | ||
| 98 | this.auditSize = (arguments.length >= 6) ? auditSize : LoaderMax.defaultAuditSize; | ||
| 99 | this.skipFailed = skipFailed; | ||
| 100 | this.skipPaused = skipPaused; | ||
| 101 | } | ||
| 102 | |||
| 103 | /** Clones the object. **/ | ||
| 104 | public function clone():LoaderMaxVars { | ||
| 105 | return _cloneProps(new LoaderMaxVars()) as LoaderMaxVars; | ||
| 106 | } | ||
| 107 | |||
| 108 | } | ||
| 109 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.91 | ||
| 3 | * DATE: 2010-09-10 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data { | ||
| 8 | import com.greensock.loading.core.LoaderCore; | ||
| 9 | import com.greensock.loading.data.core.LoaderItemVars; | ||
| 10 | |||
| 11 | import flash.display.DisplayObject; | ||
| 12 | import flash.media.SoundLoaderContext; | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Can be used instead of a generic object to define the <code>vars</code> parameter of an MP3Loader's constructor. <br /><br /> | ||
| 16 | * | ||
| 17 | * There are 2 primary benefits of using a MP3LoaderVars instance to define your MP3Loader variables: | ||
| 18 | * <ol> | ||
| 19 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in MP3Loader</li> | ||
| 20 | * <li> It enables strict data typing for improved debugging (ensuring, for example, that you don't define a Boolean value for <code>onComplete</code> where a Function is expected).</li> | ||
| 21 | * </ol> | ||
| 22 | * | ||
| 23 | * <strong>USAGE:</strong><br /><br /> | ||
| 24 | * | ||
| 25 | * Instead of <code>new MP3Loader("audio.mp3", {name:"audio", estimatedBytes:11500, autoPlay:false, onComplete:completeHandler, onProgress:progressHandler})</code>, | ||
| 26 | * you could use this utility like:<br /><br /><code> | ||
| 27 | * | ||
| 28 | * var vars:MP3LoaderVars = new MP3LoaderVars();<br /> | ||
| 29 | * vars.name = "audio";<br /> | ||
| 30 | * vars.estimatedBytes = 11500;<br /> | ||
| 31 | * vars.autoPlay = false;<br /> | ||
| 32 | * vars.onComplete = completeHandler;<br /> | ||
| 33 | * vars.onProgress = progressHandler;<br /> | ||
| 34 | * var loader:MP3Loader = new MP3Loader("audio.mp3", vars);<br /><br /></code> | ||
| 35 | * | ||
| 36 | * Some of the most common properties can be defined directly in the constructor like this:<br /><br /><code> | ||
| 37 | * | ||
| 38 | * var loader:MP3Loader = new MP3Loader("audio.mp3", new MP3LoaderVars("audio", 11500, false, completeHandler, progressHandler) );<br /><br /></code> | ||
| 39 | * | ||
| 40 | * <strong>NOTE:</strong> Using MP3LoaderVars is completely optional. If you prefer the shorter synatax with the generic Object, feel | ||
| 41 | * free to use it. The purpose of this class is simply to enable code hinting and to allow for strict data typing. <br /><br /> | ||
| 42 | * | ||
| 43 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 44 | * | ||
| 45 | * @author Jack Doyle, jack@greensock.com | ||
| 46 | */ | ||
| 47 | dynamic public class MP3LoaderVars extends LoaderItemVars { | ||
| 48 | /** @private **/ | ||
| 49 | private static var _vars:Array = ["autoPlay", | ||
| 50 | "repeat", | ||
| 51 | "volume", | ||
| 52 | "context", | ||
| 53 | "initThreshold"]; | ||
| 54 | |||
| 55 | /** By default the MP3 will begin playing immediately when enough of the file has buffered, but to prevent it from autoPlaying, set <code>autoPlay</code> to <code>false</code>. **/ | ||
| 56 | public var autoPlay:Boolean = true; | ||
| 57 | /** Number of times that the mp3 should repeat. To repeat indefinitely, use -1. Default is 0. **/ | ||
| 58 | public var repeat:int = 0; | ||
| 59 | /** A value between 0 and 1 indicating the volume at which the sound should play when the MP3Loader's controls are used to play the sound, like <code>playSound()</code> or when <code>autoPlay</code> is <code>true</code> (default volume is 1). **/ | ||
| 60 | public var volume:Number = 1; | ||
| 61 | /** To control things like the buffer time and whether or not a policy file is checked, define a <code>SoundLoaderContext</code> object. The default context is null. See Adobe's SoundLoaderContext documentation for details. **/ | ||
| 62 | public var context:SoundLoaderContext; | ||
| 63 | /** The minimum number of <code>bytesLoaded</code> to wait for before the <code>LoaderEvent.INIT</code> event is dispatched - the higher the number the more accurate the <code>duration</code> estimate will be when the INIT event is dispatched (the default value is 102400 which is 100k). The MP3's duration cannot be determined with 100% accuracy until it has completely loaded, but it is estimated with more and more accuracy as the file loads. **/ | ||
| 64 | public var initThreshold:uint = 102400; | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Constructor | ||
| 68 | * | ||
| 69 | * @param name A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". | ||
| 70 | * @param estimatedBytes Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). | ||
| 71 | * @param autoPlay By default, the MP3 will begin playing as soon as it has been adequately buffered, but to prevent it from playing initially, set <code>autoPlay</code> to <code>false</code>. | ||
| 72 | * @param onComplete A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 73 | * @param onProgress A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. | ||
| 74 | * @param onFail A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 75 | * @param noCache If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). | ||
| 76 | * @param alternateURL If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example). | ||
| 77 | * @param requireWithRoot LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. | ||
| 78 | */ | ||
| 79 | public function MP3LoaderVars(name:String="", | ||
| 80 | estimatedBytes:uint=0, | ||
| 81 | autoPlay:Boolean=true, | ||
| 82 | onComplete:Function=null, | ||
| 83 | onProgress:Function=null, | ||
| 84 | onFail:Function=null, | ||
| 85 | noCache:Boolean=false, | ||
| 86 | alternateURL:String="", | ||
| 87 | requireWithRoot:DisplayObject=null) { | ||
| 88 | super(name, estimatedBytes, onComplete, onProgress, onFail, noCache, alternateURL, requireWithRoot); | ||
| 89 | _props = _props.concat(_vars); | ||
| 90 | this.autoPlay = autoPlay; | ||
| 91 | } | ||
| 92 | |||
| 93 | /** Clones the object. **/ | ||
| 94 | public function clone():MP3LoaderVars { | ||
| 95 | return _cloneProps(new MP3LoaderVars()) as MP3LoaderVars; | ||
| 96 | } | ||
| 97 | |||
| 98 | } | ||
| 99 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data { | ||
| 8 | import com.greensock.loading.data.core.DisplayObjectLoaderVars; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | import flash.display.DisplayObjectContainer; | ||
| 12 | import flash.system.LoaderContext; | ||
| 13 | /** | ||
| 14 | * Can be used instead of a generic object to define the <code>vars</code> parameter of a SWFLoader's constructor. <br /><br /> | ||
| 15 | * | ||
| 16 | * There are 2 primary benefits of using a SWFLoaderVars instance to define your SWFLoader variables: | ||
| 17 | * <ol> | ||
| 18 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in SWFLoader</li> | ||
| 19 | * <li> It enables strict data typing for improved debugging (ensuring, for example, that you don't define a Boolean value for <code>onComplete</code> where a Function is expected).</li> | ||
| 20 | * </ol> | ||
| 21 | * | ||
| 22 | * <strong>USAGE:</strong><br /><br /> | ||
| 23 | * | ||
| 24 | * Instead of <code>new SWFLoader("main.swf", {name:"swf", estimatedBytes:11500, container:this, width:200, height:100, onComplete:completeHandler, onProgress:progressHandler})</code>, | ||
| 25 | * you could use this utility like:<br /><br /><code> | ||
| 26 | * | ||
| 27 | * var vars:SWFLoaderVars = new SWFLoaderVars();<br /> | ||
| 28 | * vars.name = "swf";<br /> | ||
| 29 | * vars.estimatedBytes = 11500;<br /> | ||
| 30 | * vars.container = this;<br /> | ||
| 31 | * vars.width = 200;<br /> | ||
| 32 | * vars.height = 100;<br /> | ||
| 33 | * vars.onComplete = completeHandler;<br /> | ||
| 34 | * vars.onProgress = progressHandler;<br /> | ||
| 35 | * var loader:SWFLoader = new SWFLoader("main.swf", vars);<br /><br /></code> | ||
| 36 | * | ||
| 37 | * Some of the most common properties can be defined directly in the constructor like this:<br /><br /><code> | ||
| 38 | * | ||
| 39 | * var loader:SWFLoader = new SWFLoader("main.swf", new SWFLoaderVars("swf", 11500, this, 200, 100, completeHandler, progressHandler) );<br /><br /></code> | ||
| 40 | * | ||
| 41 | * <strong>NOTE:</strong> Using SWFLoaderVars is completely optional. If you prefer the shorter synatax with the generic Object, feel | ||
| 42 | * free to use it. The purpose of this class is simply to enable code hinting and to allow for strict data typing. <br /><br /> | ||
| 43 | * | ||
| 44 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 45 | * | ||
| 46 | * @author Jack Doyle, jack@greensock.com | ||
| 47 | */ | ||
| 48 | dynamic public class SWFLoaderVars extends DisplayObjectLoaderVars { | ||
| 49 | /** @private **/ | ||
| 50 | private static var _vars:Array = ["context", | ||
| 51 | "autoPlay", | ||
| 52 | "integrateProgress", | ||
| 53 | "onInit", | ||
| 54 | "onChildOpen", | ||
| 55 | "onChildProgress", | ||
| 56 | "onChildComplete", | ||
| 57 | "onChildCancel", | ||
| 58 | "onChildFail"]; | ||
| 59 | |||
| 60 | /** To control whether or not a policy file is checked (which is required if you're loading an image from another domain and you want to use it in BitmapData operations), define a <code>LoaderContext</code> object. By default, the policy file <strong>will</strong> be checked when running remotely, so make sure the appropriate crossdomain.xml file is in place. See Adobe's <code>LoaderContext</code> documentation for details and precautions. **/ | ||
| 61 | public var context:LoaderContext; | ||
| 62 | /** If <code>autoPlay</code> is <code>true</code> (the default), the swf will begin playing immediately when the <code>INIT</code> event fires. To prevent this behavior, set <code>autoPlay</code> to <code>false</code> which will also mute the swf until the SWFLoader completes. **/ | ||
| 63 | public var autoPlay:Boolean; | ||
| 64 | /** By default, a SWFLoader instance will automatically look for LoaderMax loaders in the swf when it initializes. Every loader found with a <code>requireWithRoot</code> parameter set to that swf's <code>root</code> will be integrated into the SWFLoader's overall progress. The SWFLoader's <code>COMPLETE</code> event won't fire until all such loaders are also complete. If you prefer NOT to integrate the subloading loaders into the SWFLoader's overall progress, set <code>integrateProgress</code> to <code>false</code>. **/ | ||
| 65 | public var integrateProgress:Boolean = true; | ||
| 66 | /** A handler function for <code>LoaderEvent.INIT</code> events which are called when the swf has streamed enough of its content to render the first frame and determine if there are any required LoaderMax-related loaders recognized. It also adds the swf to the ContentDisplay Sprite at this point. Make sure your onInit function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 67 | public var onInit:Function; | ||
| 68 | /** A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).**/ | ||
| 69 | public var onChildOpen:Function; | ||
| 70 | /** A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) dispatches a <code>PROGRESS</code> event. To listen for changes in the SWFLoader's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the SWFLoader, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).**/ | ||
| 71 | public var onChildProgress:Function; | ||
| 72 | /** A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 73 | public var onChildComplete:Function; | ||
| 74 | /** A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 75 | public var onChildCancel:Function; | ||
| 76 | /** A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time any nested LoaderMax-related loaders (active ones that the SWFLoader found inside the subloading swf that had their <code>requireWithRoot</code> set to its <code>root</code>) fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).**/ | ||
| 77 | public var onChildFail:Function; | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Constructor | ||
| 81 | * | ||
| 82 | * @param name A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". | ||
| 83 | * @param estimatedBytes Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). | ||
| 84 | * @param container A DisplayObjectContainer into which the <code>ContentDisplay</code> Sprite should be added immediately. | ||
| 85 | * @param autoPlay If <code>autoPlay</code> is <code>true</code> (the default), the swf will begin playing immediately when the <code>INIT</code> event fires. To prevent this behavior, set <code>autoPlay</code> to <code>false</code> which will also mute the swf until the SWFLoader completes. | ||
| 86 | * @param width Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY). | ||
| 87 | * @param height Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY). | ||
| 88 | * @param scaleMode When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded image will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer):<code>"stretch" | "proportionalInside" | "proportionalOutside" | "widthOnly" | "heightOnly" | "none"</code> | ||
| 89 | * @param onComplete A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 90 | * @param onProgress A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. | ||
| 91 | * @param onFail A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 92 | * @param noCache If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). | ||
| 93 | * @param alternateURL If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various SWFLoaders for example). | ||
| 94 | * @param requireWithRoot LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. | ||
| 95 | */ | ||
| 96 | public function SWFLoaderVars(name:String="", | ||
| 97 | estimatedBytes:uint=0, | ||
| 98 | container:DisplayObjectContainer=null, | ||
| 99 | autoPlay:Boolean=true, | ||
| 100 | width:Number=NaN, | ||
| 101 | height:Number=NaN, | ||
| 102 | scaleMode:String="stretch", | ||
| 103 | onComplete:Function=null, | ||
| 104 | onProgress:Function=null, | ||
| 105 | onFail:Function=null, | ||
| 106 | noCache:Boolean=false, | ||
| 107 | alternateURL:String="", | ||
| 108 | requireWithRoot:DisplayObject=null) { | ||
| 109 | super(name, estimatedBytes, container, width, height, scaleMode, onComplete, onProgress, onFail, noCache, alternateURL, requireWithRoot); | ||
| 110 | _props = _props.concat(_vars); | ||
| 111 | this.autoPlay = autoPlay; | ||
| 112 | } | ||
| 113 | |||
| 114 | /** Clones the object. **/ | ||
| 115 | public function clone():SWFLoaderVars { | ||
| 116 | return _cloneProps(new SWFLoaderVars()) as SWFLoaderVars; | ||
| 117 | } | ||
| 118 | |||
| 119 | } | ||
| 120 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.91 | ||
| 3 | * DATE: 2010-09-01 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data { | ||
| 8 | import com.greensock.loading.data.core.DisplayObjectLoaderVars; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | import flash.display.DisplayObjectContainer; | ||
| 12 | import flash.system.LoaderContext; | ||
| 13 | /** | ||
| 14 | * Can be used instead of a generic object to define the <code>vars</code> parameter of a VideoLoader's constructor. <br /><br /> | ||
| 15 | * | ||
| 16 | * There are 2 primary benefits of using a VideoLoaderVars instance to define your VideoLoader variables: | ||
| 17 | * <ol> | ||
| 18 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in VideoLoader</li> | ||
| 19 | * <li> It enables strict data typing for improved debugging (ensuring, for example, that you don't define a Boolean value for <code>onComplete</code> where a Function is expected).</li> | ||
| 20 | * </ol> | ||
| 21 | * | ||
| 22 | * <strong>USAGE:</strong><br /><br /> | ||
| 23 | * | ||
| 24 | * Instead of <code>new VideoLoader("video.flv", {name:"video", estimatedBytes:111500, container:this, width:200, height:100, onComplete:completeHandler, onProgress:progressHandler})</code>, | ||
| 25 | * you could use this utility like:<br /><br /><code> | ||
| 26 | * | ||
| 27 | * var vars:VideoLoaderVars = new VideoLoaderVars();<br /> | ||
| 28 | * vars.name = "video";<br /> | ||
| 29 | * vars.estimatedBytes = 111500;<br /> | ||
| 30 | * vars.container = this;<br /> | ||
| 31 | * vars.width = 200;<br /> | ||
| 32 | * vars.height = 100;<br /> | ||
| 33 | * vars.onComplete = completeHandler;<br /> | ||
| 34 | * vars.onProgress = progressHandler;<br /> | ||
| 35 | * var loader:VideoLoader = new VideoLoader("video.flv", vars);<br /><br /></code> | ||
| 36 | * | ||
| 37 | * Some of the most common properties can be defined directly in the constructor like this:<br /><br /><code> | ||
| 38 | * | ||
| 39 | * var loader:VideoLoader = new VideoLoader("video.flv", new VideoLoaderVars("video", 111500, this, 200, 100, completeHandler, progressHandler) );<br /><br /></code> | ||
| 40 | * | ||
| 41 | * <strong>NOTE:</strong> Using VideoLoaderVars is completely optional. If you prefer the shorter synatax with the generic Object, feel | ||
| 42 | * free to use it. The purpose of this class is simply to enable code hinting and to allow for strict data typing. <br /><br /> | ||
| 43 | * | ||
| 44 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 45 | * | ||
| 46 | * @author Jack Doyle, jack@greensock.com | ||
| 47 | */ | ||
| 48 | dynamic public class VideoLoaderVars extends DisplayObjectLoaderVars { | ||
| 49 | /** @private **/ | ||
| 50 | private static var _vars:Array = ["bufferTime", | ||
| 51 | "autoPlay", | ||
| 52 | "smoothing", | ||
| 53 | "repeat", | ||
| 54 | "checkPolicyFile", | ||
| 55 | "estimatedDuration", | ||
| 56 | "deblocking", | ||
| 57 | "bufferMode", | ||
| 58 | "volume"]; | ||
| 59 | |||
| 60 | /** The amount of time (in seconds) that should be buffered before the video can begin playing (set <code>autoPlay</code> to <code>false</code> to pause the video initially).**/ | ||
| 61 | public var bufferTime:Number = 5; | ||
| 62 | /** By default, the video will begin playing as soon as it has been adequately buffered, but to prevent it from playing initially, set <code>autoPlay</code> to <code>false</code>. **/ | ||
| 63 | public var autoPlay:Boolean = true; | ||
| 64 | /** When <code>smoothing</code> is <code>true</code> (the default), smoothing will be enabled for the video which typically leads to better scaling results. **/ | ||
| 65 | public var smoothing:Boolean = true; | ||
| 66 | /** Number of times that the video should repeat. To repeat indefinitely, use -1. Default is 0. **/ | ||
| 67 | public var repeat:int = 0; | ||
| 68 | /** If <code>true</code>, the VideoLoader will check for a crossdomain.xml file on the remote host (only useful when loading videos from other domains - see Adobe's docs for details about NetStream's <code>checkPolicyFile</code> property). **/ | ||
| 69 | public var checkPolicyFile:Boolean; | ||
| 70 | /** Estimated duration of the video in seconds. VideoLoader will only use this value until it receives the necessary metaData from the video in order to accurately determine the video's duration. You do not need to specify an <code>estimatedDuration</code>, but doing so can help make the playProgress and some other values more accurate (until the metaData has loaded). It can also make the <code>progress/bytesLoaded/bytesTotal</code> more accurate when a <code>estimatedDuration</code> is defined, particularly in <code>bufferMode</code>.**/ | ||
| 71 | public var estimatedDuration:Number; | ||
| 72 | /** Indicates the type of filter applied to decoded video as part of post-processing. The default value is 0, which lets the video compressor apply a deblocking filter as needed. See Adobe's <code>flash.media.Video</code> class docs for details. **/ | ||
| 73 | public var deblocking:int = 0; | ||
| 74 | /** When <code>true</code>, the loader will report its progress only in terms of the video's buffer which can be very convenient if, for example, you want to display loading progress for the video's buffer or tuck it into a LoaderMax with other loaders and allow the LoaderMax to dispatch its <code>COMPLETE</code> event when the buffer is full instead of waiting for the whole file to download. When <code>bufferMode</code> is <code>true</code>, the VideoLoader will dispatch its <code>COMPLETE</code> event when the buffer is full as opposed to waiting for the entire video to load. You can toggle the <code>bufferMode</code> anytime. Please read the full <code>bufferMode</code> property ASDoc description below for details about how it affects things like <code>bytesTotal</code>.**/ | ||
| 75 | public var bufferMode:Boolean; | ||
| 76 | /** A value between 0 and 1 indicating the volume at which the video should play (default is 1).**/ | ||
| 77 | public var volume:Number = 1; | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Constructor | ||
| 81 | * | ||
| 82 | * @param name A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". | ||
| 83 | * @param estimatedBytes Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). | ||
| 84 | * @param container A DisplayObjectContainer into which the <code>ContentDisplay</code> Sprite should be added immediately. | ||
| 85 | * @param autoPlay By default, the video will begin playing as soon as it has been adequately buffered, but to prevent it from playing initially, set <code>autoPlay</code> to <code>false</code>. | ||
| 86 | * @param width Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY). | ||
| 87 | * @param height Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY). | ||
| 88 | * @param scaleMode When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded image will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer):<code>"stretch" | "proportionalInside" | "proportionalOutside" | "widthOnly" | "heightOnly" | "none"</code> | ||
| 89 | * @param onComplete A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 90 | * @param onProgress A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. | ||
| 91 | * @param onFail A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 92 | * @param noCache If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). | ||
| 93 | * @param alternateURL If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various VideoLoaders for example). | ||
| 94 | * @param requireWithRoot LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. | ||
| 95 | */ | ||
| 96 | public function VideoLoaderVars(name:String="", | ||
| 97 | estimatedBytes:uint=0, | ||
| 98 | container:DisplayObjectContainer=null, | ||
| 99 | autoPlay:Boolean=true, | ||
| 100 | width:Number=NaN, | ||
| 101 | height:Number=NaN, | ||
| 102 | scaleMode:String="stretch", | ||
| 103 | onComplete:Function=null, | ||
| 104 | onProgress:Function=null, | ||
| 105 | onFail:Function=null, | ||
| 106 | noCache:Boolean=false, | ||
| 107 | alternateURL:String="", | ||
| 108 | requireWithRoot:DisplayObject=null) { | ||
| 109 | super(name, estimatedBytes, container, width, height, scaleMode, onComplete, onProgress, onFail, noCache, alternateURL, requireWithRoot); | ||
| 110 | _props = _props.concat(_vars); | ||
| 111 | this.autoPlay = autoPlay; | ||
| 112 | } | ||
| 113 | |||
| 114 | /** Clones the object. **/ | ||
| 115 | public function clone():VideoLoaderVars { | ||
| 116 | return _cloneProps(new VideoLoaderVars()) as VideoLoaderVars; | ||
| 117 | } | ||
| 118 | |||
| 119 | } | ||
| 120 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data { | ||
| 8 | import com.greensock.loading.core.LoaderCore; | ||
| 9 | import com.greensock.loading.data.core.LoaderItemVars; | ||
| 10 | |||
| 11 | import flash.display.DisplayObject; | ||
| 12 | /** | ||
| 13 | * Can be used instead of a generic object to define the <code>vars</code> parameter of an XMLLoader's constructor. <br /><br /> | ||
| 14 | * | ||
| 15 | * There are 2 primary benefits of using a XMLLoaderVars instance to define your XMLLoader variables: | ||
| 16 | * <ol> | ||
| 17 | * <li> In most code editors, code hinting will be activated which helps remind you which special properties are available in XMLLoader</li> | ||
| 18 | * <li> It enables strict data typing for improved debugging (ensuring, for example, that you don't define a Boolean value for <code>onComplete</code> where a Function is expected).</li> | ||
| 19 | * </ol> | ||
| 20 | * | ||
| 21 | * <strong>USAGE:</strong><br /><br /> | ||
| 22 | * | ||
| 23 | * Instead of <code>new XMLLoader("getData.php", {name:"myData", estimatedBytes:1500, onComplete:completeHandler, onProgress:progressHandler})</code>, | ||
| 24 | * you could use this utility like:<br /><br /><code> | ||
| 25 | * | ||
| 26 | * var vars:XMLLoaderVars = new XMLLoaderVars();<br /> | ||
| 27 | * vars.name = "myData";<br /> | ||
| 28 | * vars.estimatedBytes = 1500;<br /> | ||
| 29 | * vars.onComplete = completeHandler;<br /> | ||
| 30 | * vars.onProgress = progressHandler;<br /> | ||
| 31 | * var loader:XMLLoader = new XMLLoader("getData.php", vars);<br /><br /></code> | ||
| 32 | * | ||
| 33 | * Some of the most common properties can be defined directly in the constructor like this:<br /><br /><code> | ||
| 34 | * | ||
| 35 | * var loader:XMLLoader = new XMLLoader("getData.php", new XMLLoaderVars("myData", 1500, completeHandler, progressHandler) );<br /><br /></code> | ||
| 36 | * | ||
| 37 | * <strong>NOTE:</strong> Using XMLLoaderVars is completely optional. If you prefer the shorter synatax with the generic Object, feel | ||
| 38 | * free to use it. The purpose of this class is simply to enable code hinting and to allow for strict data typing. <br /><br /> | ||
| 39 | * | ||
| 40 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 41 | * | ||
| 42 | * @author Jack Doyle, jack@greensock.com | ||
| 43 | */ | ||
| 44 | dynamic public class XMLLoaderVars extends LoaderItemVars { | ||
| 45 | /** @private **/ | ||
| 46 | private static var _vars:Array = ["integrateProgress", | ||
| 47 | "onChildOpen", | ||
| 48 | "onChildProgress", | ||
| 49 | "onChildComplete", | ||
| 50 | "onChildCancel", | ||
| 51 | "onChildFail"]; | ||
| 52 | |||
| 53 | /** By default, the XMLLoader will automatically look for LoaderMax-related nodes like <code><LoaderMax>, <ImageLoader>, <SWFLoader>, <XMLLoader>, <MP3Loader>, <DataLoader></code>, and <code><CSSLoader></code> inside the XML when it inits. If it finds any that have a <code>load="true"</code> attribute, it will begin loading them and integrate their progress into the XMLLoader's overall progress. Its <code>COMPLETE</code> event won't fire until all of these loaders have completed as well. If you prefer NOT to integrate the dynamically-created loader instances into the XMLLoader's overall <code>progress</code>, set <code>integrateProgress</code> to <code>false</code>. **/ | ||
| 54 | public var integrateProgress:Boolean=true; | ||
| 55 | /** A handler function for <code>LoaderEvent.CHILD_OPEN</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML begins loading. Make sure your onChildOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 56 | public var onChildOpen:Function; | ||
| 57 | /** A handler function for <code>LoaderEvent.CHILD_PROGRESS</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML dispatches a <code>PROGRESS</code> event. To listen for changes in the XMLLoader's overall progress, use the <code>onProgress</code> special property instead. You can use the LoaderEvent's <code>target.progress</code> to get the child loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. The LoaderEvent's <code>currentTarget</code> refers to the XMLLoader, so you can check its overall progress with the LoaderEvent's <code>currentTarget.progress</code>. Make sure your onChildProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 58 | public var onChildProgress:Function; | ||
| 59 | /** A handler function for <code>LoaderEvent.CHILD_COMPLETE</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML finishes loading successfully. Make sure your onChildComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 60 | public var onChildComplete:Function; | ||
| 61 | /** A handler function for <code>LoaderEvent.CHILD_CANCEL</code> events which are dispatched each time loading is aborted on any nested LoaderMax-related loaders that were defined in the XML due to either an error or because another loader was prioritized in the queue or because <code>cancel()</code> was manually called on the child loader. Make sure your onChildCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 62 | public var onChildCancel:Function; | ||
| 63 | /** A handler function for <code>LoaderEvent.CHILD_FAIL</code> events which are dispatched each time any nested LoaderMax-related loaders that were defined in the XML fails (and its <code>status</code> chances to <code>LoaderStatus.FAILED</code>). Make sure your onChildFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 64 | public var onChildFail:Function; | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Constructor | ||
| 68 | * | ||
| 69 | * @param name A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". | ||
| 70 | * @param estimatedBytes Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). | ||
| 71 | * @param onComplete A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 72 | * @param onProgress A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. | ||
| 73 | * @param onFail A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 74 | * @param noCache If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). | ||
| 75 | * @param alternateURL If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example). | ||
| 76 | * @param requireWithRoot LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. | ||
| 77 | */ | ||
| 78 | public function XMLLoaderVars(name:String="", | ||
| 79 | estimatedBytes:uint=0, | ||
| 80 | onComplete:Function=null, | ||
| 81 | onProgress:Function=null, | ||
| 82 | onFail:Function=null, | ||
| 83 | noCache:Boolean=false, | ||
| 84 | alternateURL:String="", | ||
| 85 | requireWithRoot:DisplayObject=null) { | ||
| 86 | super(name, estimatedBytes, onComplete, onProgress, onFail, noCache, alternateURL, requireWithRoot); | ||
| 87 | _props = _props.concat(_vars); | ||
| 88 | } | ||
| 89 | |||
| 90 | /** Clones the object. **/ | ||
| 91 | public function clone():XMLLoaderVars { | ||
| 92 | return _cloneProps(new XMLLoaderVars()) as XMLLoaderVars; | ||
| 93 | } | ||
| 94 | |||
| 95 | } | ||
| 96 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data.core { | ||
| 8 | import com.greensock.loading.data.core.LoaderItemVars; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | import flash.display.DisplayObjectContainer; | ||
| 12 | import flash.system.LoaderContext; | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Facilitates code hinting and data type enforcement for the <code>vars</code> object that's passed into the | ||
| 16 | * constructor of various DisplayObject-related loaders in the LoaderMax system. There is no reason to use this class directly - see | ||
| 17 | * docs for the vars classes that extend DisplayObjectLoaderVars like ImageLoaderVars, SWFLoaderVars, VideoLoaderVars, etc.<br /><br /> | ||
| 18 | * | ||
| 19 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 20 | * | ||
| 21 | * @author Jack Doyle, jack@greensock.com | ||
| 22 | */ | ||
| 23 | dynamic public class DisplayObjectLoaderVars extends LoaderItemVars { | ||
| 24 | /** @private **/ | ||
| 25 | private static var _vars:Array = ["container", | ||
| 26 | "width", | ||
| 27 | "height", | ||
| 28 | "centerRegistration", | ||
| 29 | "scaleMode", | ||
| 30 | "hAlign", | ||
| 31 | "vAlign", | ||
| 32 | "crop", | ||
| 33 | "x", | ||
| 34 | "y", | ||
| 35 | "scaleX", | ||
| 36 | "scaleY", | ||
| 37 | "rotation", | ||
| 38 | "alpha", | ||
| 39 | "visible", | ||
| 40 | "blendMode", | ||
| 41 | "bgColor", | ||
| 42 | "bgAlpha", | ||
| 43 | "onSecurityError"]; | ||
| 44 | |||
| 45 | /** A DisplayObjectContainer into which the <code>ContentDisplay</code> Sprite should be added immediately. **/ | ||
| 46 | public var container:DisplayObjectContainer; | ||
| 47 | /** Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY). **/ | ||
| 48 | public var width:Number; | ||
| 49 | /** Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY). **/ | ||
| 50 | public var height:Number; | ||
| 51 | /** If <code>true</code>, the registration point will be placed in the center of the ContentDisplay which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center. **/ | ||
| 52 | public var centerRegistration:Boolean; | ||
| 53 | /** | ||
| 54 | * When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded image will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 55 | * <ul> | ||
| 56 | * <li><code>"stretch"</code> (the default) - The image will fill the width/height exactly. </li> | ||
| 57 | * <li><code>"proportionalInside"</code> - The image will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 58 | * <li><code>"proportionalOutside"</code> - The image will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height. </li> | ||
| 59 | * <li><code>"widthOnly"</code> - Only the width of the image will be adjusted to fit.</li> | ||
| 60 | * <li><code>"heightOnly"</code> - Only the height of the image will be adjusted to fit.</li> | ||
| 61 | * <li><code>"none"</code> - No scaling of the image will occur. </li> | ||
| 62 | * </ul> | ||
| 63 | **/ | ||
| 64 | public var scaleMode:String; | ||
| 65 | /** | ||
| 66 | * When a <code>width</code> and <code>height</code> is defined, the <code>hAlign</code> determines how the image is horizontally aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 67 | * <ul> | ||
| 68 | * <li><code>"center"</code> (the default) - The image will be centered horizontally in the area</li> | ||
| 69 | * <li><code>"left"</code> - The image will be aligned with the left side of the area</li> | ||
| 70 | * <li><code>"right"</code> - The image will be aligned with the right side of the area</li> | ||
| 71 | * </ul> | ||
| 72 | **/ | ||
| 73 | public var hAlign:String="center"; | ||
| 74 | /** | ||
| 75 | * When a <code>width</code> and <code>height</code> is defined, the <code>vAlign</code> determines how the image is vertically aligned within that area. The following values are recognized (you may use the <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 76 | * <ul> | ||
| 77 | * <li><code>"center"</code> (the default) - The image will be centered vertically in the area</li> | ||
| 78 | * <li><code>"top"</code> - The image will be aligned with the top of the area</li> | ||
| 79 | * <li><code>"bottom"</code> - The image will be aligned with the bottom of the area</li> | ||
| 80 | * </ul> | ||
| 81 | **/ | ||
| 82 | public var vAlign:String="center"; | ||
| 83 | /** When a <code>width</code> and <code>height</code> are defined, setting <code>crop</code> to <code>true</code> will cause the image to be cropped within that area (by applying a <code>scrollRect</code> for maximum performance). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> or <code>"none"</code> so that any parts of the image that exceed the dimensions defined by <code>width</code> and <code>height</code> are visually chopped off. Use the <code>hAlign</code> and <code>vAlign</code> special properties to control the vertical and horizontal alignment within the cropped area. **/ | ||
| 84 | public var crop:Boolean; | ||
| 85 | /** Sets the <code>ContentDisplay</code>'s <code>x</code> property (for positioning on the stage). **/ | ||
| 86 | public var x:Number = 0; | ||
| 87 | /** Sets the <code>ContentDisplay</code>'s <code>y</code> property (for positioning on the stage). **/ | ||
| 88 | public var y:Number = 0; | ||
| 89 | /** Sets the <code>ContentDisplay</code>'s <code>scaleX</code> property. **/ | ||
| 90 | public var scaleX:Number = 1; | ||
| 91 | /** Sets the <code>ContentDisplay</code>'s <code>scaleY</code> property. **/ | ||
| 92 | public var scaleY:Number = 1; | ||
| 93 | /** Sets the <code>ContentDisplay</code>'s <code>rotation</code> property. **/ | ||
| 94 | public var rotation:Number = 0; | ||
| 95 | /** Sets the <code>ContentDisplay</code>'s <code>alpha</code> property. **/ | ||
| 96 | public var alpha:Number = 1; | ||
| 97 | /** Sets the <code>ContentDisplay</code>'s <code>visible</code> property. **/ | ||
| 98 | public var visible:Boolean = true; | ||
| 99 | /** Sets the <code>ContentDisplay</code>'s <code>blendMode</code> property. **/ | ||
| 100 | public var blendMode:String="normal"; | ||
| 101 | /** When a <code>width</code> and <code>height</code> are defined, a rectangle will be drawn inside the <code>ContentDisplay</code> Sprite immediately in order to ease the development process. It is transparent by default, but you may define a <code>bgColor</code> if you prefer. **/ | ||
| 102 | public var bgColor:uint=0; | ||
| 103 | /** Controls the alpha of the rectangle that is drawn when a <code>width</code> and <code>height</code> are defined. **/ | ||
| 104 | public var bgAlpha:Number=0; | ||
| 105 | /** A handler function for <code>LoaderEvent.SECURITY_ERROR</code> events which onError handles as well, so you can use that as more of a catch-all whereas onSecurityError is specifically for SECURITY_ERROR events. Make sure your onSecurityError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 106 | public var onSecurityError:Function; | ||
| 107 | |||
| 108 | /** | ||
| 109 | * Constructor | ||
| 110 | * | ||
| 111 | * @param name A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". | ||
| 112 | * @param estimatedBytes Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). | ||
| 113 | * @param container A DisplayObjectContainer into which the <code>ContentDisplay</code> Sprite should be added immediately. | ||
| 114 | * @param width Sets the <code>ContentDisplay</code>'s <code>width</code> property (applied before rotation, scaleX, and scaleY). | ||
| 115 | * @param height Sets the <code>ContentDisplay</code>'s <code>height</code> property (applied before rotation, scaleX, and scaleY). | ||
| 116 | * @param scaleMode When a <code>width</code> and <code>height</code> are defined, the <code>scaleMode</code> controls how the loaded image will be scaled to fit the area. The following values are recognized (you may use the <code>com.greensock.layout.ScaleMode</code> constants if you prefer):<code>"stretch" | "proportionalInside" | "proportionalOutside" | "widthOnly" | "heightOnly" | "none"</code> | ||
| 117 | * @param onComplete A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 118 | * @param onProgress A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>. | ||
| 119 | * @param onFail A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). | ||
| 120 | * @param noCache If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). | ||
| 121 | * @param alternateURL If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example). | ||
| 122 | * @param requireWithRoot LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. | ||
| 123 | */ | ||
| 124 | public function DisplayObjectLoaderVars(name:String="", | ||
| 125 | estimatedBytes:uint=0, | ||
| 126 | container:DisplayObjectContainer=null, | ||
| 127 | width:Number=NaN, | ||
| 128 | height:Number=NaN, | ||
| 129 | scaleMode:String="stretch", | ||
| 130 | onComplete:Function=null, | ||
| 131 | onProgress:Function=null, | ||
| 132 | onFail:Function=null, | ||
| 133 | noCache:Boolean=false, | ||
| 134 | alternateURL:String="", | ||
| 135 | requireWithRoot:DisplayObject=null) { | ||
| 136 | super(name, estimatedBytes, onComplete, onProgress, onFail, noCache, alternateURL, requireWithRoot); | ||
| 137 | _props = _props.concat(_vars); | ||
| 138 | this.container = container; | ||
| 139 | this.width = width; | ||
| 140 | this.height = height; | ||
| 141 | this.scaleMode = scaleMode; | ||
| 142 | } | ||
| 143 | |||
| 144 | } | ||
| 145 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data.core { | ||
| 8 | import com.greensock.loading.core.LoaderCore; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | /** | ||
| 12 | * Facilitates code hinting and data type enforcement for the <code>vars</code> object that's passed into the | ||
| 13 | * constructor of various loaders in the LoaderMax system. There is no reason to use this class directly - see | ||
| 14 | * docs for the vars classes that extend LoaderCoreVars like XMLLoaderVars, SWFLoaderVars, LoaderMaxVars, etc.<br /><br /> | ||
| 15 | * | ||
| 16 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 17 | * | ||
| 18 | * @author Jack Doyle, jack@greensock.com | ||
| 19 | */ | ||
| 20 | dynamic public class LoaderCoreVars { | ||
| 21 | /** @private **/ | ||
| 22 | private static var _vars:Array = ["name", | ||
| 23 | "onComplete", | ||
| 24 | "onProgress", | ||
| 25 | "onFail", | ||
| 26 | "requireWithRoot", | ||
| 27 | "autoDispose", | ||
| 28 | "onOpen", | ||
| 29 | "onCancel", | ||
| 30 | "onError", | ||
| 31 | "onIOError", | ||
| 32 | "onHTTPStatus"]; | ||
| 33 | |||
| 34 | /** A name that is used to identify the loader instance. This name can be fed to the <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> methods or traced at any time. Each loader's name should be unique. If you don't define one, a unique name will be created automatically, like "loader21". **/ | ||
| 35 | public var name:String; | ||
| 36 | /** A handler function for <code>LoaderEvent.COMPLETE</code> events which are dispatched when the loader has finished loading successfully. Make sure your onComplete function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 37 | public var onComplete:Function; | ||
| 38 | /** A handler function for <code>LoaderEvent.PROGRESS</code> events which are dispatched whenever the <code>bytesLoaded</code> changes. Make sure your onProgress function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can use the LoaderEvent's <code>target.progress</code> to get the loader's progress value or use its <code>target.bytesLoaded</code> and <code>target.bytesTotal</code>.**/ | ||
| 39 | public var onProgress:Function; | ||
| 40 | /** A handler function for <code>LoaderEvent.FAIL</code> events which are dispatched whenever the loader fails and its <code>status</code> changes to <code>LoaderStatus.FAILED</code>. Make sure your onFail function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 41 | public var onFail:Function; | ||
| 42 | /** LoaderMax supports <i>subloading</i>, where an object can be factored into a parent's loading progress. If you want LoaderMax to require this loader as part of its parent SWFLoader's progress, you must set the <code>requireWithRoot</code> property to your swf's <code>root</code>. For example, <code>vars.requireWithRoot = this.root;</code>. **/ | ||
| 43 | public var requireWithRoot:DisplayObject; | ||
| 44 | /** When <code>autoDispose</code> is <code>true</code>, the loader will be disposed immediately after it completes (it calls the <code>dispose()</code> method internally after dispatching its <code>COMPLETE</code> event). This will remove any listeners that were defined in the vars object (like onComplete, onProgress, onError, onInit). Once a loader is disposed, it can no longer be found with <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> - it is essentially destroyed but its content is not unloaded (you must call <code>unload()</code> or <code>dispose(true)</code> to unload its content). The default <code>autoDispose</code> value is <code>false</code>.**/ | ||
| 45 | public var autoDispose:Boolean; | ||
| 46 | /** A handler function for <code>LoaderEvent.OPEN</code> events which are dispatched when the loader begins loading. Make sure your onOpen function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).**/ | ||
| 47 | public var onOpen:Function; | ||
| 48 | /** A handler function for <code>LoaderEvent.CANCEL</code> events which are dispatched when loading is aborted due to either a failure or because another loader was prioritized or <code>cancel()</code> was manually called. Make sure your onCancel function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 49 | public var onCancel:Function; | ||
| 50 | /** A handler function for <code>LoaderEvent.ERROR</code> events which are dispatched whenever the loader experiences an error (typically an IO_ERROR or SECURITY_ERROR). An error doesn't necessarily mean the loader failed, however - to listen for when a loader fails, use the <code>onFail</code> special property. Make sure your onError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). **/ | ||
| 51 | public var onError:Function; | ||
| 52 | /** A handler function for <code>LoaderEvent.IO_ERROR</code> events which will also call the onError handler, so you can use that as more of a catch-all whereas <code>onIOError</code> is specifically for LoaderEvent.IO_ERROR events. Make sure your onIOError function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>).</li> **/ | ||
| 53 | public var onIOError:Function; | ||
| 54 | /** A handler function for <code>LoaderEvent.HTTP_STATUS</code> events. Make sure your onHTTPStatus function accepts a single parameter of type <code>LoaderEvent</code> (<code>com.greensock.events.LoaderEvent</code>). You can determine the httpStatus code using the LoaderEvent's <code>target.httpStatus</code> (LoaderItems keep track of their <code>httpStatus</code> when possible, although certain environments prevent Flash from getting httpStatus information).**/ | ||
| 55 | public var onHTTPStatus:Function; | ||
| 56 | |||
| 57 | /** @private **/ | ||
| 58 | protected var _props:Array; | ||
| 59 | |||
| 60 | |||
| 61 | /** | ||
| 62 | * Constructor | ||
| 63 | * @private | ||
| 64 | */ | ||
| 65 | public function LoaderCoreVars(name:String="", | ||
| 66 | onComplete:Function=null, | ||
| 67 | onProgress:Function=null, | ||
| 68 | onFail:Function=null, | ||
| 69 | requireWithRoot:DisplayObject=null) { | ||
| 70 | _props = _vars.slice(); | ||
| 71 | this.name = name; | ||
| 72 | this.onComplete = onComplete; | ||
| 73 | this.onProgress = onProgress; | ||
| 74 | this.onFail = onFail; | ||
| 75 | this.requireWithRoot = requireWithRoot; | ||
| 76 | } | ||
| 77 | |||
| 78 | /** @private **/ | ||
| 79 | protected function _cloneProps(vars:LoaderCoreVars):LoaderCoreVars { | ||
| 80 | for each (var p:String in _props) { | ||
| 81 | vars[p] = this[p]; | ||
| 82 | } | ||
| 83 | for (p in this) { //now do the dynamic props. | ||
| 84 | vars[p] = this[p]; | ||
| 85 | } | ||
| 86 | return vars; | ||
| 87 | } | ||
| 88 | |||
| 89 | } | ||
| 90 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-08-09 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com/LoaderMax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.data.core { | ||
| 8 | import com.greensock.loading.data.core.LoaderCoreVars; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | /** | ||
| 12 | * Facilitates code hinting and data type enforcement for the <code>vars</code> object that's passed into the | ||
| 13 | * constructor of various LoaderItems in the LoaderMax system. There is no reason to use this class directly - see | ||
| 14 | * docs for the vars classes that extend LoaderItemVars like XMLLoaderVars, SWFLoaderVars, etc.<br /><br /> | ||
| 15 | * | ||
| 16 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 17 | * | ||
| 18 | * @author Jack Doyle, jack@greensock.com | ||
| 19 | */ | ||
| 20 | dynamic public class LoaderItemVars extends LoaderCoreVars { | ||
| 21 | /** @private **/ | ||
| 22 | private static var _vars:Array = ["estimatedBytes", | ||
| 23 | "noCache", | ||
| 24 | "alternateURL"]; | ||
| 25 | |||
| 26 | /** If you define an <code>alternateURL</code>, the loader will initially try to load from its original <code>url</code> and if it fails, it will automatically (and permanently) change the loader's <code>url</code> to the <code>alternateURL</code> and try again. Think of it as a fallback or backup <code>url</code>. It is perfectly acceptable to use the same <code>alternateURL</code> for multiple loaders (maybe a default image for various ImageLoaders for example). **/ | ||
| 27 | public var alternateURL:String; | ||
| 28 | /** If <code>true</code>, a "cacheBusterID" parameter will be appended to the url with a random set of numbers to prevent caching (don't worry, this info is ignored when you <code>LoaderMax.getLoader()</code> or <code>LoaderMax.getContent()</code> by <code>url</code> or when you're running locally). **/ | ||
| 29 | public var noCache:Boolean; | ||
| 30 | /** Initially, the loader's <code>bytesTotal</code> is set to the <code>estimatedBytes</code> value (or <code>LoaderMax.defaultEstimatedBytes</code> if one isn't defined). Then, when the loader begins loading and it can accurately determine the bytesTotal, it will do so. Setting <code>estimatedBytes</code> is optional, but the more accurate the value, the more accurate your loaders' overall progress will be initially. If the loader is inserted into a LoaderMax instance (for queue management), its <code>auditSize</code> feature can attempt to automatically determine the <code>bytesTotal</code> at runtime (there is a slight performance penalty for this, however - see LoaderMax's documentation for details). **/ | ||
| 31 | public var estimatedBytes:uint; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * Constructor | ||
| 35 | * @private | ||
| 36 | */ | ||
| 37 | public function LoaderItemVars(name:String="", | ||
| 38 | estimatedBytes:uint=0, | ||
| 39 | onComplete:Function=null, | ||
| 40 | onProgress:Function=null, | ||
| 41 | onFail:Function=null, | ||
| 42 | noCache:Boolean=false, | ||
| 43 | alternateURL:String="", | ||
| 44 | requireWithRoot:DisplayObject=null) { | ||
| 45 | super(name, onComplete, onProgress, onFail, requireWithRoot); | ||
| 46 | _props = _props.concat(_vars); | ||
| 47 | this.estimatedBytes = estimatedBytes; | ||
| 48 | this.noCache = noCache; | ||
| 49 | this.alternateURL = alternateURL; | ||
| 50 | } | ||
| 51 | |||
| 52 | } | ||
| 53 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.46 | ||
| 3 | * DATE: 2010-09-15 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.display { | ||
| 8 | import com.greensock.loading.core.LoaderItem; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | import flash.display.DisplayObjectContainer; | ||
| 12 | import flash.display.Sprite; | ||
| 13 | import flash.geom.Rectangle; | ||
| 14 | /** | ||
| 15 | * A container for visual content that is loaded by any of the following: ImageLoaders, SWFLoaders, | ||
| 16 | * or VideoLoaders. It is essentially a Sprite that has a <code>loader</code> property for easily referencing | ||
| 17 | * the original loader, as well as several other useful properties for controling the placement of | ||
| 18 | * <code>rawContent</code> and the way it is scaled to fit (if at all). You can add a ContentDisplay | ||
| 19 | * to the display list or populate an array with as many as you want and then if you ever need to unload() | ||
| 20 | * the content or reload it or figure out its url, etc., you can reference your ContentDisplay's <code>loader</code> | ||
| 21 | * property like <code>myContent.loader.url</code> or <code>(myContent.loader as SWFLoader).getClass("com.greensock.TweenLite");</code> | ||
| 22 | * <br /><br /> | ||
| 23 | * | ||
| 24 | * Flex users can utilize the <code>FlexContentDisplay</code> class instead which extends <code>UIComponent</code> (a Flex requirement). | ||
| 25 | * All you need to do is set the <code>LoaderMax.contentDisplayClass</code> property to FlexContentDisplay once like: | ||
| 26 | * @example Example AS3 code:<listing version="3.0"> | ||
| 27 | import com.greensock.loading.~~; | ||
| 28 | import com.greensock.loading.display.~~; | ||
| 29 | |||
| 30 | LoaderMax.contentDisplayClass = FlexContentDisplay; | ||
| 31 | </listing> | ||
| 32 | * | ||
| 33 | * After that, all ImageLoaders, SWFLoaders, and VideoLoaders will return FlexContentDisplay objects | ||
| 34 | * as their <code>content</code> instead of regular ContentDisplay objects. <br /><br /> | ||
| 35 | * | ||
| 36 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 37 | * | ||
| 38 | * @author Jack Doyle, jack@greensock.com | ||
| 39 | */ | ||
| 40 | public class ContentDisplay extends Sprite { | ||
| 41 | /** @private **/ | ||
| 42 | protected static var _transformProps:Object = {x:1, y:1, scaleX:1, scaleY:1, rotation:1, alpha:1, visible:true, blendMode:"normal", centerRegistration:false, crop:false, scaleMode:"stretch", hAlign:"center", vAlign:"center"}; | ||
| 43 | /** @private **/ | ||
| 44 | protected var _loader:LoaderItem; | ||
| 45 | /** @private **/ | ||
| 46 | protected var _rawContent:DisplayObject; | ||
| 47 | /** @private **/ | ||
| 48 | protected var _centerRegistration:Boolean; | ||
| 49 | /** @private **/ | ||
| 50 | protected var _crop:Boolean; | ||
| 51 | /** @private **/ | ||
| 52 | protected var _scaleMode:String = "stretch"; | ||
| 53 | /** @private **/ | ||
| 54 | protected var _hAlign:String = "center"; | ||
| 55 | /** @private **/ | ||
| 56 | protected var _vAlign:String = "center"; | ||
| 57 | /** @private **/ | ||
| 58 | protected var _bgColor:uint; | ||
| 59 | /** @private **/ | ||
| 60 | protected var _bgAlpha:Number = 0; | ||
| 61 | /** @private **/ | ||
| 62 | protected var _fitWidth:Number; | ||
| 63 | /** @private **/ | ||
| 64 | protected var _fitHeight:Number; | ||
| 65 | |||
| 66 | /** @private A place to reference an object that should be protected from gc - this is used in VideoLoader in order to protect the NetStream object when the loader is disposed. **/ | ||
| 67 | public var gcProtect:*; | ||
| 68 | |||
| 69 | /** | ||
| 70 | * Constructor | ||
| 71 | * | ||
| 72 | * @param loader The Loader object that will populate the ContentDisplay's <code>rawContent</code>. | ||
| 73 | */ | ||
| 74 | public function ContentDisplay(loader:LoaderItem) { | ||
| 75 | super(); | ||
| 76 | this.loader = loader; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Removes the ContentDisplay from the display list (if necessary), dumps the <code>rawContent</code>, | ||
| 81 | * and calls <code>unload()</code> and <code>dispose()</code> on the loader (unless you define otherwise with | ||
| 82 | * the optional parameters). This essentially destroys the ContentDisplay and makes it eligible for garbage | ||
| 83 | * collection internally, although if you added any listeners manually, you should remove them as well. | ||
| 84 | * | ||
| 85 | * @param unloadLoader If <code>true</code>, <code>unload()</code> will be called on the loader. It is <code>true</code> by default. | ||
| 86 | * @param disposeLoader If <code>true</code>, <code>dispose()</code> will be called on the loader. It is <code>true</code> by default. | ||
| 87 | */ | ||
| 88 | public function dispose(unloadLoader:Boolean=true, disposeLoader:Boolean=true):void { | ||
| 89 | if (this.parent != null) { | ||
| 90 | this.parent.removeChild(this); | ||
| 91 | } | ||
| 92 | this.rawContent = null; | ||
| 93 | this.gcProtect = null; | ||
| 94 | if (_loader != null) { | ||
| 95 | if (unloadLoader) { | ||
| 96 | _loader.unload(); | ||
| 97 | } | ||
| 98 | if (disposeLoader) { | ||
| 99 | _loader.dispose(false); | ||
| 100 | _loader = null; | ||
| 101 | } | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | /** @private **/ | ||
| 106 | protected function _update():void { | ||
| 107 | var left:Number = (_centerRegistration && _fitWidth > 0) ? _fitWidth / -2 : 0; | ||
| 108 | var top:Number = (_centerRegistration && _fitHeight > 0) ? _fitHeight / -2 : 0; | ||
| 109 | if (_fitWidth > 0 && _fitHeight > 0) { | ||
| 110 | graphics.beginFill(_bgColor, _bgAlpha); | ||
| 111 | graphics.drawRect(left, top, _fitWidth, _fitHeight); | ||
| 112 | graphics.endFill(); | ||
| 113 | } | ||
| 114 | if (_rawContent == null) { | ||
| 115 | return; | ||
| 116 | } | ||
| 117 | var mc:DisplayObject = _rawContent; | ||
| 118 | var contentWidth:Number = mc.width; | ||
| 119 | var contentHeight:Number = mc.height; | ||
| 120 | if (_loader.hasOwnProperty("getClass") && !_loader.scriptAccessDenied) { //for SWFLoaders, use loaderInfo.width/height so that everything is based on the stage size, not the bounding box of the DisplayObjects that happen to be on the stage (which could be much larger or smaller than the swf's stage) | ||
| 121 | contentWidth = mc.loaderInfo.width; | ||
| 122 | contentHeight = mc.loaderInfo.height; | ||
| 123 | } | ||
| 124 | |||
| 125 | if (_fitWidth > 0 && _fitHeight > 0) { | ||
| 126 | var w:Number = _fitWidth; | ||
| 127 | var h:Number = _fitHeight; | ||
| 128 | |||
| 129 | var wGap:Number = w - contentWidth; | ||
| 130 | var hGap:Number = h - contentHeight; | ||
| 131 | |||
| 132 | if (_scaleMode != "none") { | ||
| 133 | var displayRatio:Number = w / h; | ||
| 134 | var contentRatio:Number = contentWidth / contentHeight; | ||
| 135 | if ((contentRatio < displayRatio && _scaleMode == "proportionalInside") || (contentRatio > displayRatio && _scaleMode == "proportionalOutside")) { | ||
| 136 | w = h * contentRatio; | ||
| 137 | } | ||
| 138 | if ((contentRatio > displayRatio && _scaleMode == "proportionalInside") || (contentRatio < displayRatio && _scaleMode == "proportionalOutside")) { | ||
| 139 | h = w / contentRatio; | ||
| 140 | } | ||
| 141 | |||
| 142 | if (_scaleMode != "heightOnly") { | ||
| 143 | mc.width *= w / contentWidth; | ||
| 144 | wGap = _fitWidth - w; | ||
| 145 | } | ||
| 146 | if (_scaleMode != "widthOnly") { | ||
| 147 | mc.height *= h / contentHeight; | ||
| 148 | hGap = _fitHeight - h; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | if (_hAlign == "left") { | ||
| 153 | wGap = 0; | ||
| 154 | } else if (_hAlign != "right") { | ||
| 155 | wGap *= 0.5; | ||
| 156 | } | ||
| 157 | if (_vAlign == "top") { | ||
| 158 | hGap = 0; | ||
| 159 | } else if (_vAlign != "bottom") { | ||
| 160 | hGap *= 0.5; | ||
| 161 | } | ||
| 162 | |||
| 163 | mc.x = left; | ||
| 164 | mc.y = top; | ||
| 165 | |||
| 166 | if (_crop) { | ||
| 167 | mc.scrollRect = new Rectangle(-wGap / mc.scaleX, -hGap / mc.scaleY, _fitWidth / mc.scaleX, _fitHeight / mc.scaleY); | ||
| 168 | } else { | ||
| 169 | mc.x += wGap; | ||
| 170 | mc.y += hGap; | ||
| 171 | } | ||
| 172 | } else { | ||
| 173 | mc.x = (_centerRegistration) ? -contentWidth / 2 : 0; | ||
| 174 | mc.y = (_centerRegistration) ? -contentHeight / 2 : 0; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | |||
| 179 | |||
| 180 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 181 | |||
| 182 | /** | ||
| 183 | * The width to which the <code>rawContent</code> should be fit according to the ContentDisplay's <code>scaleMode</code> | ||
| 184 | * (this width is figured before rotation, scaleX, and scaleY). When a "width" property is defined in the loader's <code>vars</code> | ||
| 185 | * property/parameter, it is automatically applied to this <code>fitWidth</code> property. For example, the following code will | ||
| 186 | * set the loader's ContentDisplay <code>fitWidth</code> to 100:<code><br /><br /> | ||
| 187 | * | ||
| 188 | * var loader:ImageLoader = new ImageLoader("photo.jpg", {width:100, height:80, container:this});</code> | ||
| 189 | * | ||
| 190 | * @see #fitHeight | ||
| 191 | * @see #scaleMode | ||
| 192 | **/ | ||
| 193 | public function get fitWidth():Number { | ||
| 194 | return _fitWidth; | ||
| 195 | } | ||
| 196 | public function set fitWidth(value:Number):void { | ||
| 197 | _fitWidth = value; | ||
| 198 | _update(); | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 202 | * The height to which the <code>rawContent</code> should be fit according to the ContentDisplay's <code>scaleMode</code> | ||
| 203 | * (this height is figured before rotation, scaleX, and scaleY). When a "height" property is defined in the loader's <code>vars</code> | ||
| 204 | * property/parameter, it is automatically applied to this <code>fitHeight</code> property. For example, the following code will | ||
| 205 | * set the loader's ContentDisplay <code>fitHeight</code> to 80:<code><br /><br /> | ||
| 206 | * | ||
| 207 | * var loader:ImageLoader = new ImageLoader("photo.jpg", {width:100, height:80, container:this});</code> | ||
| 208 | * | ||
| 209 | * @see #fitWidth | ||
| 210 | * @see #scaleMode | ||
| 211 | **/ | ||
| 212 | public function get fitHeight():Number { | ||
| 213 | return _fitHeight; | ||
| 214 | } | ||
| 215 | public function set fitHeight(value:Number):void { | ||
| 216 | _fitHeight = value; | ||
| 217 | _update(); | ||
| 218 | } | ||
| 219 | |||
| 220 | /** | ||
| 221 | * When the ContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 222 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), the <code>scaleMode</code> controls how | ||
| 223 | * the <code>rawContent</code> will be scaled to fit the area. The following values are recognized (you may use the | ||
| 224 | * <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 225 | * <ul> | ||
| 226 | * <li><code>"stretch"</code> (the default) - The <code>rawContent</code> will fill the width/height exactly.</li> | ||
| 227 | * <li><code>"proportionalInside"</code> - The <code>rawContent</code> will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 228 | * <li><code>"proportionalOutside"</code> - The <code>rawContent</code> will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height.</li> | ||
| 229 | * <li><code>"widthOnly"</code> - Only the width of the <code>rawContent</code> will be adjusted to fit.</li> | ||
| 230 | * <li><code>"heightOnly"</code> - Only the height of the <code>rawContent</code> will be adjusted to fit.</li> | ||
| 231 | * <li><code>"none"</code> - No scaling of the <code>rawContent</code> will occur.</li> | ||
| 232 | * </ul> | ||
| 233 | **/ | ||
| 234 | public function get scaleMode():String { | ||
| 235 | return _scaleMode; | ||
| 236 | } | ||
| 237 | public function set scaleMode(value:String):void { | ||
| 238 | if (value == "none" && _rawContent != null) { | ||
| 239 | _rawContent.scaleX = _rawContent.scaleY = 1; | ||
| 240 | } | ||
| 241 | _scaleMode = value; | ||
| 242 | _update(); | ||
| 243 | } | ||
| 244 | |||
| 245 | /** | ||
| 246 | * If <code>true</code>, the ContentDisplay's registration point will be placed in the center of the <code>rawContent</code> | ||
| 247 | * which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center. | ||
| 248 | * @see #scaleMode | ||
| 249 | **/ | ||
| 250 | public function get centerRegistration():Boolean { | ||
| 251 | return _centerRegistration; | ||
| 252 | } | ||
| 253 | public function set centerRegistration(value:Boolean):void { | ||
| 254 | _centerRegistration = value; | ||
| 255 | _update(); | ||
| 256 | } | ||
| 257 | |||
| 258 | /** | ||
| 259 | * When the ContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 260 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), setting <code>crop</code> to | ||
| 261 | * <code>true</code> will cause the <code>rawContent</code> to be cropped within that area (by applying a <code>scrollRect</code> | ||
| 262 | * for maximum performance). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> | ||
| 263 | * or <code>"none"</code> so that any parts of the <code>rawContent</code> that exceed the dimensions defined by | ||
| 264 | * <code>fitWidth</code> and <code>fitHeight</code> are visually chopped off. Use the <code>hAlign</code> and | ||
| 265 | * <code>vAlign</code> properties to control the vertical and horizontal alignment within the cropped area. | ||
| 266 | * | ||
| 267 | * @see #scaleMode | ||
| 268 | **/ | ||
| 269 | public function get crop():Boolean { | ||
| 270 | return _crop; | ||
| 271 | } | ||
| 272 | public function set crop(value:Boolean):void { | ||
| 273 | _crop = value; | ||
| 274 | _update(); | ||
| 275 | } | ||
| 276 | |||
| 277 | /** | ||
| 278 | * When the ContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 279 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), the <code>hAlign</code> determines how | ||
| 280 | * the <code>rawContent</code> is horizontally aligned within that area. The following values are recognized (you may use the | ||
| 281 | * <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 282 | * <ul> | ||
| 283 | * <li><code>"center"</code> (the default) - The <code>rawContent</code> will be centered horizontally in the ContentDisplay</li> | ||
| 284 | * <li><code>"left"</code> - The <code>rawContent</code> will be aligned with the left side of the ContentDisplay</li> | ||
| 285 | * <li><code>"right"</code> - The <code>rawContent</code> will be aligned with the right side of the ContentDisplay</li> | ||
| 286 | * </ul> | ||
| 287 | * @see #scaleMode | ||
| 288 | * @see #vAlign | ||
| 289 | **/ | ||
| 290 | public function get hAlign():String { | ||
| 291 | return _hAlign; | ||
| 292 | } | ||
| 293 | public function set hAlign(value:String):void { | ||
| 294 | _hAlign = value; | ||
| 295 | _update(); | ||
| 296 | } | ||
| 297 | |||
| 298 | /** | ||
| 299 | * When the ContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 300 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), the <code>vAlign</code> determines how | ||
| 301 | * the <code>rawContent</code> is vertically aligned within that area. The following values are recognized (you may use the | ||
| 302 | * <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 303 | * <ul> | ||
| 304 | * <li><code>"center"</code> (the default) - The <code>rawContent</code> will be centered vertically in the ContentDisplay</li> | ||
| 305 | * <li><code>"top"</code> - The <code>rawContent</code> will be aligned with the top of the ContentDisplay</li> | ||
| 306 | * <li><code>"bottom"</code> - The <code>rawContent</code> will be aligned with the bottom of the ContentDisplay</li> | ||
| 307 | * </ul> | ||
| 308 | * @see #scaleMode | ||
| 309 | * @see #hAlign | ||
| 310 | **/ | ||
| 311 | public function get vAlign():String { | ||
| 312 | return _vAlign; | ||
| 313 | } | ||
| 314 | public function set vAlign(value:String):void { | ||
| 315 | _vAlign = value; | ||
| 316 | _update(); | ||
| 317 | } | ||
| 318 | |||
| 319 | /** | ||
| 320 | * When the ContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 321 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), a rectangle will be drawn inside the | ||
| 322 | * ContentDisplay object immediately in order to ease the development process (for example, you can add <code>ROLL_OVER/ROLL_OUT</code> | ||
| 323 | * event listeners immediately). It is transparent by default, but you may define a <code>bgAlpha</code> if you prefer. | ||
| 324 | * @see #bgAlpha | ||
| 325 | * @see #fitWidth | ||
| 326 | * @see #fitHeight | ||
| 327 | **/ | ||
| 328 | public function get bgColor():uint { | ||
| 329 | return _bgColor; | ||
| 330 | } | ||
| 331 | public function set bgColor(value:uint):void { | ||
| 332 | _bgColor = value; | ||
| 333 | _update(); | ||
| 334 | } | ||
| 335 | |||
| 336 | /** | ||
| 337 | * Controls the alpha of the rectangle that is drawn when the ContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> | ||
| 338 | * properties are defined (or <code>width</code> and <code>height</code> in the loader's <code>vars</code> property/parameter). | ||
| 339 | * @see #bgColor | ||
| 340 | * @see #fitWidth | ||
| 341 | * @see #fitHeight | ||
| 342 | **/ | ||
| 343 | public function get bgAlpha():Number { | ||
| 344 | return _bgAlpha; | ||
| 345 | } | ||
| 346 | public function set bgAlpha(value:Number):void { | ||
| 347 | _bgAlpha = value; | ||
| 348 | _update(); | ||
| 349 | } | ||
| 350 | |||
| 351 | /** The raw content which can be a Bitmap, a MovieClip, a Loader, or a Video depending on the type of loader associated with the ContentDisplay. **/ | ||
| 352 | public function get rawContent():* { | ||
| 353 | return _rawContent; | ||
| 354 | } | ||
| 355 | |||
| 356 | public function set rawContent(value:*):void { | ||
| 357 | if (_rawContent != null && _rawContent != value && _rawContent.parent == this) { | ||
| 358 | removeChild(_rawContent); | ||
| 359 | } | ||
| 360 | _rawContent = value as DisplayObject; | ||
| 361 | if (_rawContent == null) { | ||
| 362 | return; | ||
| 363 | } | ||
| 364 | addChildAt(_rawContent as DisplayObject, 0); | ||
| 365 | _update(); | ||
| 366 | } | ||
| 367 | |||
| 368 | /** The loader whose rawContent populates this ContentDisplay. If you get the loader's <code>content</code>, it will return this ContentDisplay object. **/ | ||
| 369 | public function get loader():LoaderItem { | ||
| 370 | return _loader; | ||
| 371 | } | ||
| 372 | public function set loader(value:LoaderItem):void { | ||
| 373 | _loader = value; | ||
| 374 | if (_loader == null) { | ||
| 375 | return; | ||
| 376 | } else if (!_loader.hasOwnProperty("setContentDisplay")) { | ||
| 377 | throw new Error("Incompatible loader used for a ContentDisplay"); | ||
| 378 | } | ||
| 379 | this.name = _loader.name; | ||
| 380 | if (_loader.vars.container is DisplayObjectContainer) { | ||
| 381 | (_loader.vars.container as DisplayObjectContainer).addChild(this); | ||
| 382 | } | ||
| 383 | var type:String; | ||
| 384 | for (var p:String in _transformProps) { | ||
| 385 | if (p in _loader.vars) { | ||
| 386 | type = typeof(_transformProps[p]); | ||
| 387 | this[p] = (type == "number") ? Number(_loader.vars[p]) : (type == "string") ? String(_loader.vars[p]) : Boolean(_loader.vars[p]); | ||
| 388 | } | ||
| 389 | } | ||
| 390 | _bgColor = uint(_loader.vars.bgColor); | ||
| 391 | _bgAlpha = ("bgAlpha" in _loader.vars) ? Number(_loader.vars.bgAlpha) : ("bgColor" in _loader.vars) ? 1 : 0; | ||
| 392 | _fitWidth = ("fitWidth" in _loader.vars) ? Number(_loader.vars.fitWidth) : Number(_loader.vars.width); | ||
| 393 | _fitHeight = ("fitHeight" in _loader.vars) ? Number(_loader.vars.fitHeight) : Number(_loader.vars.height); | ||
| 394 | _update(); | ||
| 395 | if (_loader.content != this) { | ||
| 396 | (_loader as Object).setContentDisplay(this); | ||
| 397 | } | ||
| 398 | this.rawContent = (_loader as Object).rawContent; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.46 | ||
| 3 | * DATE: 2010-09-15 | ||
| 4 | * AS3 | ||
| 5 | * UPDATES AND DOCS AT: http://www.greensock.com/loadermax/ | ||
| 6 | **/ | ||
| 7 | package com.greensock.loading.display { | ||
| 8 | import com.greensock.loading.core.LoaderItem; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | import flash.display.DisplayObjectContainer; | ||
| 12 | import flash.geom.Matrix; | ||
| 13 | import flash.geom.Rectangle; | ||
| 14 | import flash.media.Video; | ||
| 15 | |||
| 16 | import mx.core.UIComponent; | ||
| 17 | /** | ||
| 18 | * A container for visual content that is loaded by any of the following: ImageLoaders, SWFLoaders, | ||
| 19 | * or VideoLoaders which is to be used in Flex. It is essentially a UIComponent that has a <code>loader</code> | ||
| 20 | * property for easily referencing the original loader, as well as several other useful properties for | ||
| 21 | * controling the placement of <code>rawContent</code> and the way it is scaled to fit (if at all). That way, | ||
| 22 | * you can add a FlexContentDisplay to the display list or populate an array with as many as you want and then if | ||
| 23 | * you ever need to unload() the content or reload it or figure out its url, etc., you can reference your | ||
| 24 | * FlexContentDisplay's <code>loader</code> property like <code>myContent.loader.url</code> or | ||
| 25 | * <code>(myContent.loader as SWFLoader).getClass("com.greensock.TweenLite");</code>. For | ||
| 26 | * <br /><br /> | ||
| 27 | * | ||
| 28 | * <strong>IMPORTANT</strong>: In order for the LoaderMax loaders to use FlexContentDisplay instead of | ||
| 29 | * the regular ContentDisplay class, you must set the <code>LoaderMax.contentDisplayClass</code> property | ||
| 30 | * to FlexContentDisplay once like: | ||
| 31 | * @example Example AS3 code:<listing version="3.0"> | ||
| 32 | import com.greensock.loading.~~; | ||
| 33 | import com.greensock.loading.display.~~; | ||
| 34 | |||
| 35 | LoaderMax.contentDisplayClass = FlexContentDisplay; | ||
| 36 | </listing> | ||
| 37 | * | ||
| 38 | * After that, all ImageLoaders, SWFLoaders, and VideoLoaders will return FlexContentDisplay objects | ||
| 39 | * as their <code>content</code> instead of regular ContentDisplay objects. <br /><br /> | ||
| 40 | * | ||
| 41 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 42 | * | ||
| 43 | * @author Jack Doyle, jack@greensock.com | ||
| 44 | */ | ||
| 45 | public class FlexContentDisplay extends UIComponent { | ||
| 46 | /** @private **/ | ||
| 47 | protected static var _transformProps:Object = {x:1, y:1, scaleX:1, scaleY:1, rotation:1, alpha:1, visible:true, blendMode:"normal", centerRegistration:false, crop:false, scaleMode:"stretch", hAlign:"center", vAlign:"center"}; | ||
| 48 | /** @private **/ | ||
| 49 | protected var _loader:LoaderItem; | ||
| 50 | /** @private **/ | ||
| 51 | protected var _rawContent:DisplayObject; | ||
| 52 | /** @private **/ | ||
| 53 | protected var _centerRegistration:Boolean; | ||
| 54 | /** @private **/ | ||
| 55 | protected var _crop:Boolean; | ||
| 56 | /** @private **/ | ||
| 57 | protected var _scaleMode:String = "stretch"; | ||
| 58 | /** @private **/ | ||
| 59 | protected var _hAlign:String = "center"; | ||
| 60 | /** @private **/ | ||
| 61 | protected var _vAlign:String = "center"; | ||
| 62 | /** @private **/ | ||
| 63 | protected var _bgColor:uint; | ||
| 64 | /** @private **/ | ||
| 65 | protected var _bgAlpha:Number = 0; | ||
| 66 | /** @private **/ | ||
| 67 | protected var _fitWidth:Number; | ||
| 68 | /** @private **/ | ||
| 69 | protected var _fitHeight:Number; | ||
| 70 | |||
| 71 | /** @private A place to reference an object that should be protected from gc - this is used in VideoLoader in order to protect the NetStream object when the loader is disposed. **/ | ||
| 72 | public var gcProtect:*; | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Constructor | ||
| 76 | * | ||
| 77 | * @param loader The Loader object that will populate the FlexContentDisplay's <code>rawContent</code>. | ||
| 78 | */ | ||
| 79 | public function FlexContentDisplay(loader:LoaderItem) { | ||
| 80 | super(); | ||
| 81 | this.loader = loader; | ||
| 82 | } | ||
| 83 | /** | ||
| 84 | * Removes the FlexContentDisplay from the display list (if necessary), dumps the <code>rawContent</code>, | ||
| 85 | * and calls <code>unload()</code> and <code>dispose()</code> on the loader (unless you define otherwise with | ||
| 86 | * the optional parameters). This essentially destroys the FlexContentDisplay and makes it eligible for garbage | ||
| 87 | * collection internally, although if you added any listeners manually, you should remove them as well. | ||
| 88 | * | ||
| 89 | * @param unloadLoader If <code>true</code>, <code>unload()</code> will be called on the loader. It is <code>true</code> by default. | ||
| 90 | * @param disposeLoader If <code>true</code>, <code>dispose()</code> will be called on the loader. It is <code>true</code> by default. | ||
| 91 | */ | ||
| 92 | public function dispose(unloadLoader:Boolean=true, disposeLoader:Boolean=true):void { | ||
| 93 | if (this.parent != null) { | ||
| 94 | if (this.parent.hasOwnProperty("addElement")) { | ||
| 95 | (this.parent as Object).removeElement(this); | ||
| 96 | } else { | ||
| 97 | this.parent.removeChild(this); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | this.rawContent = null; | ||
| 101 | this.gcProtect = null; | ||
| 102 | if (_loader != null) { | ||
| 103 | if (unloadLoader) { | ||
| 104 | _loader.unload(); | ||
| 105 | } | ||
| 106 | if (disposeLoader) { | ||
| 107 | _loader.dispose(false); | ||
| 108 | _loader = null; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | /** @private **/ | ||
| 114 | protected function _update():void { | ||
| 115 | var left:Number = (_centerRegistration && _fitWidth > 0) ? _fitWidth / -2 : 0; | ||
| 116 | var top:Number = (_centerRegistration && _fitHeight > 0) ? _fitHeight / -2 : 0; | ||
| 117 | if (_fitWidth > 0 && _fitHeight > 0) { | ||
| 118 | graphics.beginFill(_bgColor, _bgAlpha); | ||
| 119 | graphics.drawRect(left, top, _fitWidth, _fitHeight); | ||
| 120 | graphics.endFill(); | ||
| 121 | } | ||
| 122 | if (_rawContent == null) { | ||
| 123 | return; | ||
| 124 | } | ||
| 125 | var mc:DisplayObject = _rawContent; | ||
| 126 | var contentWidth:Number = mc.width; | ||
| 127 | var contentHeight:Number = mc.height; | ||
| 128 | if (_loader.hasOwnProperty("getClass") && !_loader.scriptAccessDenied) { //for SWFLoaders, use loaderInfo.width/height so that everything is based on the stage size, not the bounding box of the DisplayObjects that happen to be on the stage (which could be much larger or smaller than the swf's stage) | ||
| 129 | contentWidth = mc.loaderInfo.width; | ||
| 130 | contentHeight = mc.loaderInfo.height; | ||
| 131 | } | ||
| 132 | |||
| 133 | if (_fitWidth > 0 && _fitHeight > 0) { | ||
| 134 | var w:Number = _fitWidth; | ||
| 135 | var h:Number = _fitHeight; | ||
| 136 | |||
| 137 | var wGap:Number = w - contentWidth; | ||
| 138 | var hGap:Number = h - contentHeight; | ||
| 139 | |||
| 140 | if (_scaleMode != "none") { | ||
| 141 | var displayRatio:Number = w / h; | ||
| 142 | var contentRatio:Number = contentWidth / contentHeight; | ||
| 143 | if ((contentRatio < displayRatio && _scaleMode == "proportionalInside") || (contentRatio > displayRatio && _scaleMode == "proportionalOutside")) { | ||
| 144 | w = h * contentRatio; | ||
| 145 | } | ||
| 146 | if ((contentRatio > displayRatio && _scaleMode == "proportionalInside") || (contentRatio < displayRatio && _scaleMode == "proportionalOutside")) { | ||
| 147 | h = w / contentRatio; | ||
| 148 | } | ||
| 149 | |||
| 150 | if (_scaleMode != "heightOnly") { | ||
| 151 | mc.width *= w / contentWidth; | ||
| 152 | wGap = _fitWidth - w; | ||
| 153 | } | ||
| 154 | if (_scaleMode != "widthOnly") { | ||
| 155 | mc.height *= h / contentHeight; | ||
| 156 | hGap = _fitHeight - h; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | if (_hAlign == "left") { | ||
| 161 | wGap = 0; | ||
| 162 | } else if (_hAlign != "right") { | ||
| 163 | wGap *= 0.5; | ||
| 164 | } | ||
| 165 | if (_vAlign == "top") { | ||
| 166 | hGap = 0; | ||
| 167 | } else if (_vAlign != "bottom") { | ||
| 168 | hGap *= 0.5; | ||
| 169 | } | ||
| 170 | |||
| 171 | mc.x = left; | ||
| 172 | mc.y = top; | ||
| 173 | |||
| 174 | if (_crop) { | ||
| 175 | mc.scrollRect = new Rectangle(-wGap / mc.scaleX, -hGap / mc.scaleY, _fitWidth / mc.scaleX, _fitHeight / mc.scaleY); | ||
| 176 | } else { | ||
| 177 | mc.x += wGap; | ||
| 178 | mc.y += hGap; | ||
| 179 | } | ||
| 180 | } else { | ||
| 181 | mc.x = (_centerRegistration) ? -contentWidth / 2 : 0; | ||
| 182 | mc.y = (_centerRegistration) ? -contentHeight / 2 : 0; | ||
| 183 | } | ||
| 184 | measure(); | ||
| 185 | } | ||
| 186 | |||
| 187 | override protected function measure():void { | ||
| 188 | var bounds:Rectangle = this.getBounds(this); | ||
| 189 | this.explicitWidth = bounds.width; | ||
| 190 | this.explicitHeight = bounds.height; | ||
| 191 | if (this.parent) { | ||
| 192 | bounds = this.getBounds(this.parent); | ||
| 193 | this.width = bounds.width; | ||
| 194 | this.height = bounds.height; | ||
| 195 | } | ||
| 196 | super.measure(); | ||
| 197 | } | ||
| 198 | |||
| 199 | //---- GETTERS / SETTERS ------------------------------------------------------------------------- | ||
| 200 | |||
| 201 | /** | ||
| 202 | * The width to which the <code>rawContent</code> should be fit according to the FlexContentDisplay's <code>scaleMode</code> | ||
| 203 | * (this width is figured before rotation, scaleX, and scaleY). When a "width" property is defined in the loader's <code>vars</code> | ||
| 204 | * property/parameter, it is automatically applied to this <code>fitWidth</code> property. For example, the following code will | ||
| 205 | * set the loader's FlexContentDisplay <code>fitWidth</code> to 100:<code><br /><br /> | ||
| 206 | * | ||
| 207 | * var loader:ImageLoader = new ImageLoader("photo.jpg", {width:100, height:80, container:this});</code> | ||
| 208 | * | ||
| 209 | * @see #fitHeight | ||
| 210 | * @see #scaleMode | ||
| 211 | **/ | ||
| 212 | public function get fitWidth():Number { | ||
| 213 | return _fitWidth; | ||
| 214 | } | ||
| 215 | public function set fitWidth(value:Number):void { | ||
| 216 | _fitWidth = value; | ||
| 217 | _update(); | ||
| 218 | } | ||
| 219 | |||
| 220 | /** | ||
| 221 | * The height to which the <code>rawContent</code> should be fit according to the FlexContentDisplay's <code>scaleMode</code> | ||
| 222 | * (this height is figured before rotation, scaleX, and scaleY). When a "height" property is defined in the loader's <code>vars</code> | ||
| 223 | * property/parameter, it is automatically applied to this <code>fitHeight</code> property. For example, the following code will | ||
| 224 | * set the loader's FlexContentDisplay <code>fitHeight</code> to 80:<code><br /><br /> | ||
| 225 | * | ||
| 226 | * var loader:ImageLoader = new ImageLoader("photo.jpg", {width:100, height:80, container:this});</code> | ||
| 227 | * | ||
| 228 | * @see #fitWidth | ||
| 229 | * @see #scaleMode | ||
| 230 | **/ | ||
| 231 | public function get fitHeight():Number { | ||
| 232 | return _fitHeight; | ||
| 233 | } | ||
| 234 | public function set fitHeight(value:Number):void { | ||
| 235 | _fitHeight = value; | ||
| 236 | _update(); | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * When the FlexContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 241 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), the <code>scaleMode</code> controls how | ||
| 242 | * the <code>rawContent</code> will be scaled to fit the area. The following values are recognized (you may use the | ||
| 243 | * <code>com.greensock.layout.ScaleMode</code> constants if you prefer): | ||
| 244 | * <ul> | ||
| 245 | * <li><code>"stretch"</code> (the default) - The <code>rawContent</code> will fill the width/height exactly.</li> | ||
| 246 | * <li><code>"proportionalInside"</code> - The <code>rawContent</code> will be scaled proportionally to fit inside the area defined by the width/height</li> | ||
| 247 | * <li><code>"proportionalOutside"</code> - The <code>rawContent</code> will be scaled proportionally to completely fill the area, allowing portions of it to exceed the bounds defined by the width/height.</li> | ||
| 248 | * <li><code>"widthOnly"</code> - Only the width of the <code>rawContent</code> will be adjusted to fit.</li> | ||
| 249 | * <li><code>"heightOnly"</code> - Only the height of the <code>rawContent</code> will be adjusted to fit.</li> | ||
| 250 | * <li><code>"none"</code> - No scaling of the <code>rawContent</code> will occur.</li> | ||
| 251 | * </ul> | ||
| 252 | **/ | ||
| 253 | public function get scaleMode():String { | ||
| 254 | return _scaleMode; | ||
| 255 | } | ||
| 256 | public function set scaleMode(value:String):void { | ||
| 257 | if (value == "none" && _rawContent != null) { | ||
| 258 | _rawContent.scaleX = _rawContent.scaleY = 1; | ||
| 259 | } | ||
| 260 | _scaleMode = value; | ||
| 261 | _update(); | ||
| 262 | } | ||
| 263 | |||
| 264 | /** | ||
| 265 | * If <code>true</code>, the FlexContentDisplay's registration point will be placed in the center of the <code>rawContent</code> | ||
| 266 | * which can be useful if, for example, you want to animate its scale and have it grow/shrink from its center. | ||
| 267 | * @see #scaleMode | ||
| 268 | **/ | ||
| 269 | public function get centerRegistration():Boolean { | ||
| 270 | return _centerRegistration; | ||
| 271 | } | ||
| 272 | public function set centerRegistration(value:Boolean):void { | ||
| 273 | _centerRegistration = value; | ||
| 274 | _update(); | ||
| 275 | } | ||
| 276 | |||
| 277 | /** | ||
| 278 | * When the FlexContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 279 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), setting <code>crop</code> to | ||
| 280 | * <code>true</code> will cause the <code>rawContent</code> to be cropped within that area (by applying a <code>scrollRect</code> | ||
| 281 | * for maximum performance). This is typically useful when the <code>scaleMode</code> is <code>"proportionalOutside"</code> | ||
| 282 | * or <code>"none"</code> so that any parts of the <code>rawContent</code> that exceed the dimensions defined by | ||
| 283 | * <code>fitWidth</code> and <code>fitHeight</code> are visually chopped off. Use the <code>hAlign</code> and | ||
| 284 | * <code>vAlign</code> properties to control the vertical and horizontal alignment within the cropped area. | ||
| 285 | * | ||
| 286 | * @see #scaleMode | ||
| 287 | **/ | ||
| 288 | public function get crop():Boolean { | ||
| 289 | return _crop; | ||
| 290 | } | ||
| 291 | public function set crop(value:Boolean):void { | ||
| 292 | _crop = value; | ||
| 293 | _update(); | ||
| 294 | } | ||
| 295 | |||
| 296 | /** | ||
| 297 | * When the FlexContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 298 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), the <code>hAlign</code> determines how | ||
| 299 | * the <code>rawContent</code> is horizontally aligned within that area. The following values are recognized (you may use the | ||
| 300 | * <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 301 | * <ul> | ||
| 302 | * <li><code>"center"</code> (the default) - The <code>rawContent</code> will be centered horizontally in the FlexContentDisplay</li> | ||
| 303 | * <li><code>"left"</code> - The <code>rawContent</code> will be aligned with the left side of the FlexContentDisplay</li> | ||
| 304 | * <li><code>"right"</code> - The <code>rawContent</code> will be aligned with the right side of the FlexContentDisplay</li> | ||
| 305 | * </ul> | ||
| 306 | * @see #scaleMode | ||
| 307 | * @see #vAlign | ||
| 308 | **/ | ||
| 309 | public function get hAlign():String { | ||
| 310 | return _hAlign; | ||
| 311 | } | ||
| 312 | public function set hAlign(value:String):void { | ||
| 313 | _hAlign = value; | ||
| 314 | _update(); | ||
| 315 | } | ||
| 316 | |||
| 317 | /** | ||
| 318 | * When the FlexContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 319 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), the <code>vAlign</code> determines how | ||
| 320 | * the <code>rawContent</code> is vertically aligned within that area. The following values are recognized (you may use the | ||
| 321 | * <code>com.greensock.layout.AlignMode</code> constants if you prefer): | ||
| 322 | * <ul> | ||
| 323 | * <li><code>"center"</code> (the default) - The <code>rawContent</code> will be centered vertically in the FlexContentDisplay</li> | ||
| 324 | * <li><code>"top"</code> - The <code>rawContent</code> will be aligned with the top of the FlexContentDisplay</li> | ||
| 325 | * <li><code>"bottom"</code> - The <code>rawContent</code> will be aligned with the bottom of the FlexContentDisplay</li> | ||
| 326 | * </ul> | ||
| 327 | * @see #scaleMode | ||
| 328 | * @see #hAlign | ||
| 329 | **/ | ||
| 330 | public function get vAlign():String { | ||
| 331 | return _vAlign; | ||
| 332 | } | ||
| 333 | public function set vAlign(value:String):void { | ||
| 334 | _vAlign = value; | ||
| 335 | _update(); | ||
| 336 | } | ||
| 337 | |||
| 338 | /** | ||
| 339 | * When the FlexContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> properties are defined (or <code>width</code> | ||
| 340 | * and <code>height</code> in the loader's <code>vars</code> property/parameter), a rectangle will be drawn inside the | ||
| 341 | * FlexContentDisplay object immediately in order to ease the development process (for example, you can add <code>ROLL_OVER/ROLL_OUT</code> | ||
| 342 | * event listeners immediately). It is transparent by default, but you may define a <code>bgAlpha</code> if you prefer. | ||
| 343 | * @see #bgAlpha | ||
| 344 | * @see #fitWidth | ||
| 345 | * @see #fitHeight | ||
| 346 | **/ | ||
| 347 | public function get bgColor():uint { | ||
| 348 | return _bgColor; | ||
| 349 | } | ||
| 350 | public function set bgColor(value:uint):void { | ||
| 351 | _bgColor = value; | ||
| 352 | _update(); | ||
| 353 | } | ||
| 354 | |||
| 355 | /** | ||
| 356 | * Controls the alpha of the rectangle that is drawn when the FlexContentDisplay's <code>fitWidth</code> and <code>fitHeight</code> | ||
| 357 | * properties are defined (or <code>width</code> and <code>height</code> in the loader's <code>vars</code> property/parameter). | ||
| 358 | * @see #bgColor | ||
| 359 | * @see #fitWidth | ||
| 360 | * @see #fitHeight | ||
| 361 | **/ | ||
| 362 | public function get bgAlpha():Number { | ||
| 363 | return _bgAlpha; | ||
| 364 | } | ||
| 365 | public function set bgAlpha(value:Number):void { | ||
| 366 | _bgAlpha = value; | ||
| 367 | _update(); | ||
| 368 | } | ||
| 369 | |||
| 370 | |||
| 371 | /** The raw content which can be a Bitmap, a MovieClip, a Loader, or a Video depending on the type of loader associated with the FlexContentDisplay. **/ | ||
| 372 | public function get rawContent():* { | ||
| 373 | return _rawContent; | ||
| 374 | } | ||
| 375 | |||
| 376 | public function set rawContent(value:*):void { | ||
| 377 | if (_rawContent != null && _rawContent != value && _rawContent.parent == this) { | ||
| 378 | removeChild(_rawContent); | ||
| 379 | } | ||
| 380 | _rawContent = value as DisplayObject; | ||
| 381 | if (_rawContent == null) { | ||
| 382 | return; | ||
| 383 | } | ||
| 384 | addChildAt(_rawContent as DisplayObject, 0); | ||
| 385 | _update(); | ||
| 386 | } | ||
| 387 | |||
| 388 | /** The loader whose rawContent populates this FlexContentDisplay. If you get the loader's <code>content</code>, it will return this FlexContentDisplay object. **/ | ||
| 389 | public function get loader():LoaderItem { | ||
| 390 | return _loader; | ||
| 391 | } | ||
| 392 | |||
| 393 | public function set loader(value:LoaderItem):void { | ||
| 394 | _loader = value; | ||
| 395 | if (value == null) { | ||
| 396 | return; | ||
| 397 | } else if (!_loader.hasOwnProperty("setContentDisplay")) { | ||
| 398 | throw new Error("Incompatible loader used for a FlexContentDisplay"); | ||
| 399 | } | ||
| 400 | this.name = _loader.name; | ||
| 401 | if (_loader.vars.container is DisplayObjectContainer) { | ||
| 402 | if (_loader.vars.container.hasOwnProperty("addElement")) { | ||
| 403 | (_loader.vars.container as Object).addElement(this); | ||
| 404 | } else { | ||
| 405 | (_loader.vars.container as DisplayObjectContainer).addChild(this); | ||
| 406 | } | ||
| 407 | } | ||
| 408 | var type:String; | ||
| 409 | for (var p:String in _transformProps) { | ||
| 410 | if (p in _loader.vars) { | ||
| 411 | type = typeof(_transformProps[p]); | ||
| 412 | this[p] = (type == "number") ? Number(_loader.vars[p]) : (type == "string") ? String(_loader.vars[p]) : Boolean(_loader.vars[p]); | ||
| 413 | } | ||
| 414 | } | ||
| 415 | _bgColor = uint(_loader.vars.bgColor); | ||
| 416 | _bgAlpha = ("bgAlpha" in _loader.vars) ? Number(_loader.vars.bgAlpha) : ("bgColor" in _loader.vars) ? 1 : 0; | ||
| 417 | _fitWidth = ("fitWidth" in _loader.vars) ? Number(_loader.vars.fitWidth) : Number(_loader.vars.width); | ||
| 418 | _fitHeight = ("fitHeight" in _loader.vars) ? Number(_loader.vars.fitHeight) : Number(_loader.vars.height); | ||
| 419 | _update(); | ||
| 420 | if (_loader.content != this) { | ||
| 421 | (_loader as Object).setContentDisplay(this); | ||
| 422 | } | ||
| 423 | this.rawContent = (_loader as Object).rawContent; | ||
| 424 | } | ||
| 425 | } | ||
| 426 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.21 (beta) | ||
| 3 | * DATE: 2010-04-21 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.motionPaths { | ||
| 8 | import flash.display.Graphics; | ||
| 9 | import flash.geom.Matrix; | ||
| 10 | /** | ||
| 11 | * A CirclePath2D defines a circular path on which a PathFollower can be placed, making it simple to tween objects | ||
| 12 | * along a circle or oval (make an oval by altering the width/height/scaleX/scaleY properties). A PathFollower's | ||
| 13 | * position along the path is described using its <code>progress</code> property, a value between 0 and 1 where | ||
| 14 | * 0 is at the beginning of the path, 0.5 is in the middle, and 1 is at the very end of the path. So to tween a | ||
| 15 | * PathFollower along the path, you can simply tween its <code>progress</code> property. To tween ALL of the | ||
| 16 | * followers on the path at once, you can tween the CirclePath2D's <code>progress</code> property. PathFollowers | ||
| 17 | * automatically wrap so that if the <code>progress</code> value exceeds 1 or drops below 0, it shows up on | ||
| 18 | * the other end of the path.<br /><br /> | ||
| 19 | * | ||
| 20 | * Since CirclePath2D extends the Shape class, you can add an instance to the display list to see a line representation | ||
| 21 | * of the path drawn which can be helpful especially during the production phase. Use <code>lineStyle()</code> | ||
| 22 | * to adjust the color, thickness, and other attributes of the line that is drawn (or set the CirclePath2D's | ||
| 23 | * <code>visible</code> property to false or don't add it to the display list if you don't want to see the line | ||
| 24 | * at all). You can also adjust all of its properties like <code>radius, scaleX, scaleY, rotation, width, height, x,</code> | ||
| 25 | * and <code>y</code>. That means you can tween those values as well to achieve very dynamic, complex effects with ease.<br /><br /> | ||
| 26 | * | ||
| 27 | * @example Example AS3 code:<listing version="3.0"> | ||
| 28 | import com.greensock.~~; | ||
| 29 | import com.greensock.plugins.~~; | ||
| 30 | import com.greensock.motionPaths.~~; | ||
| 31 | TweenPlugin.activate([CirclePath2DPlugin]); //only needed once in your swf, and only if you plan to use the CirclePath2D tweening feature for convenience | ||
| 32 | |||
| 33 | //create a circle motion path at coordinates x:150, y:150 with a radius of 100 | ||
| 34 | var circle:CirclePath2D = new CirclePath2D(150, 150, 100); | ||
| 35 | |||
| 36 | //tween mc along the path from the bottom (90 degrees) to 315 degrees in the counter-clockwise direction and make an extra revolution | ||
| 37 | TweenLite.to(mc, 3, {circlePath2D:{path:circle, startAngle:90, endAngle:315, direction:Direction.COUNTER_CLOCKWISE, extraRevolutions:1}}); | ||
| 38 | |||
| 39 | //tween the circle's rotation, scaleX, scaleY, x, and y properties: | ||
| 40 | TweenLite.to(circle, 3, {rotation:180, scaleX:0.5, scaleY:2, x:250, y:200}); | ||
| 41 | |||
| 42 | //show the path visually by adding it to the display list (optional) | ||
| 43 | this.addChild(circle); | ||
| 44 | |||
| 45 | |||
| 46 | //--- Instead of using the plugin, you could manually manage followers and tween their "progress" property... | ||
| 47 | |||
| 48 | //make the MovieClip "mc2" follow the circle and start at a position of 90 degrees (this returns a PathFollower instance) | ||
| 49 | var follower:PathFollower = circle.addFollower(mc2, circle.angleToProgress(90)); | ||
| 50 | |||
| 51 | //tween the follower clockwise along the path to 315 degrees | ||
| 52 | TweenLite.to(follower, 2, {progress:circle.followerTween(follower, 315, Direction.CLOCKWISE)}); | ||
| 53 | |||
| 54 | //tween the follower counter-clockwise to 200 degrees and add an extra revolution | ||
| 55 | TweenLite.to(follower, 2, {progress:circle.followerTween(follower, 200, Direction.COUNTER_CLOCKWISE, 1)}); | ||
| 56 | </listing> | ||
| 57 | * | ||
| 58 | * <b>NOTES</b><br /> | ||
| 59 | * <ul> | ||
| 60 | * <li>All followers's positions are automatically updated when you alter the MotionPath that they're following.</li> | ||
| 61 | * <li>To tween all followers along the path at once, simply tween the MotionPath's <code>progress</code> | ||
| 62 | * property which will provide better performance than tweening each follower independently.</li> | ||
| 63 | * </ul> | ||
| 64 | * | ||
| 65 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 66 | * | ||
| 67 | * @author Jack Doyle, jack@greensock.com | ||
| 68 | */ | ||
| 69 | public class CirclePath2D extends MotionPath { | ||
| 70 | /** @private **/ | ||
| 71 | protected var _radius:Number; | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Constructor | ||
| 75 | * | ||
| 76 | * @param x The x coordinate of the origin (center) of the circle | ||
| 77 | * @param y The y coordinate of the origin (center) of the circle | ||
| 78 | * @param radius The radius of the circle | ||
| 79 | */ | ||
| 80 | public function CirclePath2D(x:Number, y:Number, radius:Number) { | ||
| 81 | super(); | ||
| 82 | _radius = radius; | ||
| 83 | super.x = x; | ||
| 84 | super.y = y; | ||
| 85 | } | ||
| 86 | |||
| 87 | /** @private **/ | ||
| 88 | override protected function renderAll():void { | ||
| 89 | var angle:Number, px:Number, py:Number; | ||
| 90 | var m:Matrix = this.transform.matrix; | ||
| 91 | var a:Number = m.a, b:Number = m.b, c:Number = m.c, d:Number = m.d, tx:Number = m.tx, ty:Number = m.ty; | ||
| 92 | var f:PathFollower = _rootFollower; | ||
| 93 | while (f) { | ||
| 94 | angle = f.cachedProgress * Math.PI * 2; | ||
| 95 | px = Math.cos(angle) * _radius; | ||
| 96 | py = Math.sin(angle) * _radius; | ||
| 97 | f.target.x = px * a + py * c + tx; | ||
| 98 | f.target.y = px * b + py * d + ty; | ||
| 99 | |||
| 100 | if (f.autoRotate) { | ||
| 101 | angle += Math.PI / 2; | ||
| 102 | px = Math.cos(angle) * _radius; | ||
| 103 | py = Math.sin(angle) * _radius; | ||
| 104 | f.target.rotation = Math.atan2(px * m.b + py * m.d, px * m.a + py * m.c) * _RAD2DEG + f.rotationOffset; | ||
| 105 | } | ||
| 106 | |||
| 107 | f = f.cachedNext; | ||
| 108 | } | ||
| 109 | if (_redrawLine && this.visible && this.parent) { | ||
| 110 | var g:Graphics = this.graphics; | ||
| 111 | g.clear(); | ||
| 112 | g.lineStyle(_thickness, _color, _lineAlpha, _pixelHinting, _scaleMode, _caps, _joints, _miterLimit); | ||
| 113 | g.drawCircle(0, 0, _radius); | ||
| 114 | _redrawLine = false; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | /** @inheritDoc **/ | ||
| 119 | override public function renderObjectAt(target:Object, progress:Number, autoRotate:Boolean=false, rotationOffset:Number=0):void { | ||
| 120 | var angle:Number = progress * Math.PI * 2; | ||
| 121 | var m:Matrix = this.transform.matrix; | ||
| 122 | var px:Number = Math.cos(angle) * _radius; | ||
| 123 | var py:Number = Math.sin(angle) * _radius; | ||
| 124 | target.x = px * m.a + py * m.c + m.tx; | ||
| 125 | target.y = px * m.b + py * m.d + m.ty; | ||
| 126 | |||
| 127 | if (autoRotate) { | ||
| 128 | angle += Math.PI / 2; | ||
| 129 | px = Math.cos(angle) * _radius; | ||
| 130 | py = Math.sin(angle) * _radius; | ||
| 131 | target.rotation = Math.atan2(px * m.b + py * m.d, px * m.a + py * m.c) * _RAD2DEG + rotationOffset; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | |||
| 136 | /** | ||
| 137 | * Translates an angle (in degrees or radians) to the associated progress value | ||
| 138 | * on the CirclePath2D. For example, to position <code>mc</code> on the CirclePath2D at 90 degrees | ||
| 139 | * (bottom), you'd do:<br /><br /><code> | ||
| 140 | * | ||
| 141 | * var follower:PathFollower = myCircle.addFollower(mc, myCircle.angleToProgress(90));<br /> | ||
| 142 | * | ||
| 143 | * </code> | ||
| 144 | * | ||
| 145 | * @param angle The angle whose progress value you want to determine | ||
| 146 | * @param useRadians If you prefer to define the angle in radians instead of degrees, set this to true (it is false by default) | ||
| 147 | * @return The progress value associated with the angle | ||
| 148 | */ | ||
| 149 | public function angleToProgress(angle:Number, useRadians:Boolean=false):Number { | ||
| 150 | var revolution:Number = useRadians ? Math.PI * 2 : 360; | ||
| 151 | if (angle < 0) { | ||
| 152 | angle += (int(-angle / revolution) + 1) * revolution; | ||
| 153 | } else if (angle > revolution) { | ||
| 154 | angle -= int(angle / revolution) * revolution; | ||
| 155 | } | ||
| 156 | return angle / revolution; | ||
| 157 | } | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Translates a progress value (typically between 0 and 1 where 0 is the beginning of the path, | ||
| 161 | * 0.5 is in the middle, and 1 is at the end) to the associated angle on the CirclePath2D. | ||
| 162 | * For example, to find out what angle a particular PathFollower is at, you'd do:<br /><br /><code> | ||
| 163 | * | ||
| 164 | * var angle:Number = myCircle.progressToAngle(myFollower.progress, false);<br /> | ||
| 165 | * | ||
| 166 | * </code> | ||
| 167 | * | ||
| 168 | * @param progress The progress value to translate into an angle | ||
| 169 | * @param useRadians If you prefer that the angle be described in radians instead of degrees, set this to true (it is false by default) | ||
| 170 | * @return The angle (in degrees or radians depending on the useRadians value) associated with the progress value. | ||
| 171 | */ | ||
| 172 | public function progressToAngle(progress:Number, useRadians:Boolean=false):Number { | ||
| 173 | var revolution:Number = useRadians ? Math.PI * 2 : 360; | ||
| 174 | return progress * revolution; | ||
| 175 | } | ||
| 176 | |||
| 177 | /** | ||
| 178 | * Simplifies tweening by determining a relative change in the progress value of a follower based on the | ||
| 179 | * endAngle, direction, and extraRevolutions that you define. For example, to tween <code>myFollower</code> | ||
| 180 | * from wherever it is currently to the position at 315 degrees, moving in the COUNTER_CLOCKWISE direction | ||
| 181 | * and going 2 extra revolutions, you could do:<br /><br /><code> | ||
| 182 | * | ||
| 183 | * TweenLite.to(myFollower, 2, {progress:myCircle.followerTween(myFollower, 315, Direction.COUNTER_CLOCKWISE, 2)}); | ||
| 184 | * </code> | ||
| 185 | * | ||
| 186 | * @param follower The PathFollower (or its associated target) that will be tweened (determines the start angle) | ||
| 187 | * @param endAngle The destination (end) angle | ||
| 188 | * @param direction The direction in which to travel - options are <code>Direction.CLOCKWISE</code> ("clockwise"), <code>Direction.COUNTER_CLOCKWISE</code> ("counterClockwise"), or <code>Direction.SHORTEST</code> ("shortest"). | ||
| 189 | * @param extraRevolutions If instead of going directly to the endAngle, you want the target to travel one or more extra revolutions around the path before going to the endAngle, define that number of revolutions here. | ||
| 190 | * @param useRadians If you prefer to define the angle in radians instead of degrees, set this to true (it is false by default) | ||
| 191 | * @return A String representing the amount of change in the <code>progress</code> value (feel free to cast it as a Number if you want, but it returns a String because TweenLite/Max/Nano recognize Strings as relative values. | ||
| 192 | */ | ||
| 193 | public function followerTween(follower:*, endAngle:Number, direction:String="clockwise", extraRevolutions:uint=0, useRadians:Boolean=false):String { | ||
| 194 | var revolution:Number = useRadians ? Math.PI * 2 : 360; | ||
| 195 | return String(anglesToProgressChange(getFollower(follower).progress * revolution, endAngle, direction, extraRevolutions, useRadians)); | ||
| 196 | } | ||
| 197 | |||
| 198 | /** | ||
| 199 | * Returns the amount of <code>progress</code> change between two angles on the CirclePath2D, allowing special | ||
| 200 | * parameters like direction and extraRevolutions. | ||
| 201 | * | ||
| 202 | * @param startAngle The starting angle | ||
| 203 | * @param endAngle The ending angle | ||
| 204 | * @param direction The direction in which to travel - options are <code>Direction.CLOCKWISE</code> ("clockwise"), <code>Direction.COUNTER_CLOCKWISE</code> ("counterClockwise"), or <code>Direction.SHORTEST</code> ("shortest"). | ||
| 205 | * @param extraRevolutions If instead of going directly to the endAngle, you want the target to travel one or more extra revolutions around the path before going to the endAngle, define that number of revolutions here. | ||
| 206 | * @param useRadians If you prefer to define the angle in radians instead of degrees, set this to true (it is false by default) | ||
| 207 | * @return A Number representing the amount of change in the <code>progress</code> value. | ||
| 208 | */ | ||
| 209 | public function anglesToProgressChange(startAngle:Number, endAngle:Number, direction:String="clockwise", extraRevolutions:uint=0, useRadians:Boolean=false):Number { | ||
| 210 | var revolution:Number = useRadians ? Math.PI * 2 : 360; | ||
| 211 | var dif:Number = endAngle - startAngle; | ||
| 212 | if (dif < 0 && direction == "clockwise") { | ||
| 213 | dif += (int(-dif / revolution) + 1) * revolution; | ||
| 214 | } else if (dif > 0 && direction == "counterClockwise") { | ||
| 215 | dif -= (int(dif / revolution) + 1) * revolution; | ||
| 216 | } else if (direction == "shortest") { | ||
| 217 | dif = dif % revolution; | ||
| 218 | if (dif != dif % (revolution * 0.5)) { | ||
| 219 | dif = (dif < 0) ? dif + revolution : dif - revolution; | ||
| 220 | } | ||
| 221 | } | ||
| 222 | if (dif < 0) { | ||
| 223 | dif -= extraRevolutions * revolution; | ||
| 224 | } else { | ||
| 225 | dif += extraRevolutions * revolution; | ||
| 226 | } | ||
| 227 | return dif / revolution; | ||
| 228 | } | ||
| 229 | |||
| 230 | /** radius of the circle (does not factor in any transformations like scaleX/scaleY) **/ | ||
| 231 | public function get radius():Number { | ||
| 232 | return _radius; | ||
| 233 | } | ||
| 234 | public function set radius(value:Number):void { | ||
| 235 | _radius = value; | ||
| 236 | _redrawLine = true; | ||
| 237 | renderAll(); | ||
| 238 | } | ||
| 239 | |||
| 240 | |||
| 241 | } | ||
| 242 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.1 (beta) | ||
| 3 | * DATE: 1/19/2010 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.motionPaths { | ||
| 8 | |||
| 9 | /** | ||
| 10 | * Constants for defining the direction in which to travel on a MotionPath (like <code>CLOCKWISE, COUNTER_CLOCKWISE, SHORTEST,</code> etc.). <br /><br /> | ||
| 11 | * | ||
| 12 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 13 | * | ||
| 14 | * @author Jack Doyle, jack@greensock.com | ||
| 15 | */ | ||
| 16 | public class Direction { | ||
| 17 | public static const CLOCKWISE:String="clockwise"; | ||
| 18 | public static const COUNTER_CLOCKWISE:String="counterClockwise"; | ||
| 19 | public static const SHORTEST:String="shortest"; | ||
| 20 | } | ||
| 21 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.11 (beta) | ||
| 3 | * DATE: 2010-05-04 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.motionPaths { | ||
| 8 | import flash.display.Graphics; | ||
| 9 | import flash.geom.Matrix; | ||
| 10 | import flash.geom.Point; | ||
| 11 | |||
| 12 | /** | ||
| 13 | * A LinePath2D defines a path (using as many Points as you want) on which a PathFollower can be | ||
| 14 | * placed and animated. A PathFollower's position along the path is described using the PathFollower's | ||
| 15 | * <code>progress</code> property, a value between 0 and 1 where 0 is at the beginning of the path, | ||
| 16 | * 0.5 is in the middle, and 1 is at the very end. To tween a PathFollower along the path, simply tween its | ||
| 17 | * <code>progress</code> property. To tween ALL of the followers on the path at once, you can tween the | ||
| 18 | * LinePath2D's <code>progress</code> property which performs better than tweening every PathFollower's | ||
| 19 | * <code>progress</code> property individually. PathFollowers automatically wrap so that if the | ||
| 20 | * <code>progress</code> value exceeds 1 it continues at the beginning of the path, meaning that tweening | ||
| 21 | * its <code>progress</code> from 0 to 2 would have the same effect as tweening it from 0 to 1 twice | ||
| 22 | * (it would appear to loop).<br /><br /> | ||
| 23 | * | ||
| 24 | * Since LinePath2D extends the Shape class, you can add an instance to the display list to see a line representation | ||
| 25 | * of the path drawn which can be particularly helpful during the production phase. Use <code>lineStyle()</code> | ||
| 26 | * to adjust the color, thickness, and other attributes of the line that is drawn (or set the LinePath2D's | ||
| 27 | * <code>visible</code> property to false or don't add it to the display list if you don't want to see the line | ||
| 28 | * at all). You can also adjust all of its properties like <code>scaleX, scaleY, rotation, width, height, x,</code> | ||
| 29 | * and <code>y</code>. That means you can tween those values as well to achieve very dynamic, complex effects | ||
| 30 | * with ease.<br /><br /> | ||
| 31 | * | ||
| 32 | * @example Example AS3 code:<listing version="3.0"> | ||
| 33 | import com.greensock.~~; | ||
| 34 | import com.greensock.easing.~~; | ||
| 35 | import com.greensock.motionPaths.~~; | ||
| 36 | import flash.geom.Point; | ||
| 37 | |||
| 38 | //create a LinePath2D with 5 Points | ||
| 39 | var path:LinePath2D = new LinePath2D([new Point(0, 0), | ||
| 40 | new Point(100, 100), | ||
| 41 | new Point(350, 150), | ||
| 42 | new Point(50, 200), | ||
| 43 | new Point(550, 400)]); | ||
| 44 | |||
| 45 | //add it to the display list so we can see it (you can skip this if you prefer) | ||
| 46 | addChild(path); | ||
| 47 | |||
| 48 | //create an array containing 30 blue squares | ||
| 49 | var boxes:Array = []; | ||
| 50 | for (var i:int = 0; i < 30; i++) { | ||
| 51 | boxes.push(createSquare(10, 0x0000FF)); | ||
| 52 | } | ||
| 53 | |||
| 54 | //distribute the blue squares evenly across the entire path and set them to autoRotate | ||
| 55 | path.distribute(boxes, 0, 1, true); | ||
| 56 | |||
| 57 | //put a red square exactly halfway through the 2nd segment | ||
| 58 | path.addFollower(createSquare(10, 0xFF0000), path.getSegmentProgress(2, 0.5)); | ||
| 59 | |||
| 60 | //tween all of the squares through the path once (wrapping when they reach the end) | ||
| 61 | TweenMax.to(path, 20, {progress:1}); | ||
| 62 | |||
| 63 | //while the squares are animating through the path, tween the path's position and rotation too! | ||
| 64 | TweenMax.to(path, 3, {rotation:180, x:550, y:400, ease:Back.easeOut, delay:3}); | ||
| 65 | |||
| 66 | //method for creating squares | ||
| 67 | function createSquare(size:Number, color:uint=0xFF0000):Shape { | ||
| 68 | var s:Shape = new Shape(); | ||
| 69 | s.graphics.beginFill(color, 1); | ||
| 70 | s.graphics.drawRect(-size * 0.5, -size * 0.5, size, size); | ||
| 71 | s.graphics.endFill(); | ||
| 72 | this.addChild(s); | ||
| 73 | return s; | ||
| 74 | } | ||
| 75 | </listing> | ||
| 76 | * | ||
| 77 | * <b>NOTES</b><br /> | ||
| 78 | * <ul> | ||
| 79 | * <li>All followers' positions are automatically updated when you alter the MotionPath that they're following.</li> | ||
| 80 | * <li>To tween all followers along the path at once, simply tween the MotionPath's <code>progress</code> | ||
| 81 | * property which will provide better performance than tweening each follower independently.</li> | ||
| 82 | * </ul> | ||
| 83 | * | ||
| 84 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 85 | * | ||
| 86 | * @author Jack Doyle, jack@greensock.com | ||
| 87 | */ | ||
| 88 | public class LinePath2D extends MotionPath { | ||
| 89 | /** @private **/ | ||
| 90 | protected var _first:PathPoint; | ||
| 91 | /** @private **/ | ||
| 92 | protected var _points:Array; | ||
| 93 | /** @private **/ | ||
| 94 | protected var _totalLength:Number; | ||
| 95 | /** @private **/ | ||
| 96 | protected var _hasAutoRotate:Boolean; | ||
| 97 | /** @private **/ | ||
| 98 | protected var _prevMatrix:Matrix; | ||
| 99 | |||
| 100 | /** If true, the LinePath2D will analyze every Point whenever it renders to see if any Point's x or y value has changed, thus making it possible to tween them dynamically. Setting <code>autoUpdatePoints</code> to <code>true</code> increases the CPU load due to the extra processing, so only set it to <code>true</code> if you plan to change one or more of the Points' position. **/ | ||
| 101 | public var autoUpdatePoints:Boolean; | ||
| 102 | |||
| 103 | /** | ||
| 104 | * Constructor | ||
| 105 | * | ||
| 106 | * @param points An array of Points that define the line | ||
| 107 | * @param x The x coordinate of the origin of the line | ||
| 108 | * @param y The y coordinate of the origin of the line | ||
| 109 | * @param autoUpdatePoints If true, the LinePath2D will analyze every Point whenever it renders to see if any Point's x or y value has changed, thus making it possible to tween them dynamically. Setting <code>autoUpdatePoints</code> to <code>true</code> increases the CPU load due to the extra processing, so only set it to <code>true</code> if you plan to change one or more of the Points' position. | ||
| 110 | */ | ||
| 111 | public function LinePath2D(points:Array=null, x:Number=0, y:Number=0, autoUpdatePoints:Boolean=false) { | ||
| 112 | super(); | ||
| 113 | _points = []; | ||
| 114 | _totalLength = 0; | ||
| 115 | this.autoUpdatePoints = autoUpdatePoints; | ||
| 116 | if (points != null) { | ||
| 117 | insertMultiplePoints(points, 0); | ||
| 118 | } | ||
| 119 | super.x = x; | ||
| 120 | super.y = y; | ||
| 121 | } | ||
| 122 | |||
| 123 | /** | ||
| 124 | * Adds a Point to the end of the current LinePath2D (essentially redefining its end point). | ||
| 125 | * | ||
| 126 | * @param point A Point describing the local coordinates through which the line should be drawn. | ||
| 127 | **/ | ||
| 128 | public function appendPoint(point:Point):void { | ||
| 129 | _insertPoint(point, _points.length, false); | ||
| 130 | } | ||
| 131 | |||
| 132 | /** | ||
| 133 | * Inserts a Point at a particular index value in the <code>points</code> array, similar to splice() in an array. | ||
| 134 | * For example, if a LinePath2D instance has 3 Points already and you want to insert a new Point right after the | ||
| 135 | * first one, you would do:<br /><br /><code> | ||
| 136 | * | ||
| 137 | * var path:LinePath2D = new LinePath2D([new Point(0, 0), <br /> | ||
| 138 | * new Point(100, 50), <br /> | ||
| 139 | * new Point(200, 300)]); <br /> | ||
| 140 | * path.insertPoint(new Point(50, 50), 1); <br /><br /></code> | ||
| 141 | * | ||
| 142 | * @param point A Point describing the local coordinates through which the line should be drawn. | ||
| 143 | * @param index The index value in the <code>points</code> array at which the Point should be inserted. | ||
| 144 | **/ | ||
| 145 | public function insertPoint(point:Point, index:uint=0):void { | ||
| 146 | _insertPoint(point, index, false); | ||
| 147 | } | ||
| 148 | |||
| 149 | /** @private **/ | ||
| 150 | protected function _insertPoint(point:Point, index:uint, skipOrganize:Boolean):void { | ||
| 151 | _points.splice(index, 0, new PathPoint(point)); | ||
| 152 | if (!skipOrganize) { | ||
| 153 | _organize(); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | |||
| 158 | /** | ||
| 159 | * Appends multiple Points to the end of the <code>points</code> array. Identical to | ||
| 160 | * the <code>appendPoint()</code> method, but accepts an array of Points instead of just one. | ||
| 161 | * | ||
| 162 | * @param points An array of Points to append. | ||
| 163 | */ | ||
| 164 | public function appendMultiplePoints(points:Array):void { | ||
| 165 | insertMultiplePoints(points, _points.length); | ||
| 166 | } | ||
| 167 | |||
| 168 | /** | ||
| 169 | * Inserts multiple Points into the <code>points</code> array at a particular index/position. | ||
| 170 | * Identical to the <code>insertPoint()</code> method, but accepts an array of points instead of just one. | ||
| 171 | * | ||
| 172 | * @param points An array of Points to insert. | ||
| 173 | * @param index The index value in the <code>points</code> array at which the Points should be inserted. | ||
| 174 | */ | ||
| 175 | public function insertMultiplePoints(points:Array, index:uint=0):void { | ||
| 176 | var l:int = points.length; | ||
| 177 | for (var i:int = 0; i < l; i++) { | ||
| 178 | _insertPoint(points[i], index + i, true); | ||
| 179 | } | ||
| 180 | _organize(); | ||
| 181 | } | ||
| 182 | |||
| 183 | /** | ||
| 184 | * Removes a particular Point instance from the <code>points</code> array. | ||
| 185 | * | ||
| 186 | * @param point The Point object to remove from the <code>points</code> array. | ||
| 187 | */ | ||
| 188 | public function removePoint(point:Point):void { | ||
| 189 | var i:int = _points.length; | ||
| 190 | while (--i > -1) { | ||
| 191 | if (_points[i].point == point) { | ||
| 192 | _points.splice(i, 1); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | _organize(); | ||
| 196 | } | ||
| 197 | |||
| 198 | /** | ||
| 199 | * Removes the Point that resides at a particular index/position in the <code>points</code> array. | ||
| 200 | * Just like in arrays, the index is zero-based. For example, to remove the second Point in the array, | ||
| 201 | * do <code>removePointByIndex(1)</code>; | ||
| 202 | * | ||
| 203 | * @param index The index value of the Point that should be removed from the <code>points</code> array. | ||
| 204 | */ | ||
| 205 | public function removePointByIndex(index:uint):void { | ||
| 206 | _points.splice(index, 1); | ||
| 207 | _organize(); | ||
| 208 | } | ||
| 209 | |||
| 210 | /** @private **/ | ||
| 211 | protected function _organize():void { | ||
| 212 | _totalLength = 0; | ||
| 213 | _hasAutoRotate = false; | ||
| 214 | var last:int = _points.length - 1; | ||
| 215 | if (last == -1) { | ||
| 216 | _first = null; | ||
| 217 | } else if (last == 0) { | ||
| 218 | _first = _points[0]; | ||
| 219 | _first.progress = _first.xChange = _first.yChange = _first.length = 0; | ||
| 220 | return; | ||
| 221 | } | ||
| 222 | var pp:PathPoint; | ||
| 223 | for (var i:int = 0; i <= last; i++) { | ||
| 224 | if (_points[i] != null) { | ||
| 225 | pp = _points[i]; | ||
| 226 | pp.x = pp.point.x; | ||
| 227 | pp.y = pp.point.y; | ||
| 228 | if (i == last) { | ||
| 229 | pp.length = 0; | ||
| 230 | pp.next = null; | ||
| 231 | } else { | ||
| 232 | pp.next = _points[i + 1]; | ||
| 233 | pp.xChange = pp.next.x - pp.x; | ||
| 234 | pp.yChange = pp.next.y - pp.y; | ||
| 235 | pp.length = Math.sqrt(pp.xChange * pp.xChange + pp.yChange * pp.yChange); | ||
| 236 | _totalLength += pp.length; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | _first = pp = _points[0]; | ||
| 241 | var curTotal:Number = 0; | ||
| 242 | while (pp) { | ||
| 243 | pp.progress = curTotal / _totalLength; | ||
| 244 | curTotal += pp.length; | ||
| 245 | pp = pp.next; | ||
| 246 | } | ||
| 247 | _updateAngles(); | ||
| 248 | } | ||
| 249 | |||
| 250 | /** @private **/ | ||
| 251 | protected function _updateAngles():void { | ||
| 252 | var m:Matrix = this.transform.matrix; | ||
| 253 | var pp:PathPoint = _first; | ||
| 254 | while (pp) { | ||
| 255 | pp.angle = Math.atan2(pp.xChange * m.b + pp.yChange * m.d, pp.xChange * m.a + pp.yChange * m.c) * _RAD2DEG; | ||
| 256 | pp = pp.next; | ||
| 257 | } | ||
| 258 | _prevMatrix = m; | ||
| 259 | } | ||
| 260 | |||
| 261 | /** @private **/ | ||
| 262 | override protected function renderAll():void { | ||
| 263 | if (_first == null || _points.length <= 1) { | ||
| 264 | return; | ||
| 265 | } | ||
| 266 | var updatedAngles:Boolean = false; | ||
| 267 | var px:Number, py:Number, pp:PathPoint, followerProgress:Number, pathProg:Number; | ||
| 268 | var m:Matrix = this.transform.matrix; | ||
| 269 | var a:Number = m.a, b:Number = m.b, c:Number = m.c, d:Number = m.d, tx:Number = m.tx, ty:Number = m.ty; | ||
| 270 | var f:PathFollower = _rootFollower; | ||
| 271 | |||
| 272 | if (autoUpdatePoints) { | ||
| 273 | pp = _first; | ||
| 274 | while (pp) { | ||
| 275 | if (pp.point.x != pp.x || pp.point.y != pp.y) { | ||
| 276 | _organize(); | ||
| 277 | _redrawLine = true; | ||
| 278 | renderAll(); | ||
| 279 | return; | ||
| 280 | } | ||
| 281 | pp = pp.next; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | while (f) { | ||
| 286 | |||
| 287 | followerProgress = f.cachedProgress; | ||
| 288 | pp = _first; | ||
| 289 | while (pp != null && pp.next.progress < followerProgress) { | ||
| 290 | pp = pp.next; | ||
| 291 | } | ||
| 292 | |||
| 293 | if (pp != null) { | ||
| 294 | pathProg = (followerProgress - pp.progress) / (pp.length / _totalLength); | ||
| 295 | px = pp.x + pathProg * pp.xChange; | ||
| 296 | py = pp.y + pathProg * pp.yChange; | ||
| 297 | f.target.x = px * a + py * c + tx; | ||
| 298 | f.target.y = px * b + py * d + ty; | ||
| 299 | |||
| 300 | if (f.autoRotate) { | ||
| 301 | if (!updatedAngles && (_prevMatrix.a != a || _prevMatrix.b != b || _prevMatrix.c != c || _prevMatrix.d != d)) { | ||
| 302 | _updateAngles(); //only need to update the angles once during the render cycle | ||
| 303 | updatedAngles = true; | ||
| 304 | } | ||
| 305 | f.target.rotation = pp.angle + f.rotationOffset; | ||
| 306 | } | ||
| 307 | } | ||
| 308 | |||
| 309 | f = f.cachedNext; | ||
| 310 | } | ||
| 311 | if (_redrawLine && this.visible && this.parent) { | ||
| 312 | var g:Graphics = this.graphics; | ||
| 313 | g.clear(); | ||
| 314 | g.lineStyle(_thickness, _color, _lineAlpha, _pixelHinting, _scaleMode, _caps, _joints, _miterLimit); | ||
| 315 | pp = _first; | ||
| 316 | g.moveTo(pp.x, pp.y); | ||
| 317 | while (pp) { | ||
| 318 | g.lineTo(pp.x, pp.y); | ||
| 319 | pp = pp.next; | ||
| 320 | } | ||
| 321 | _redrawLine = false; | ||
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | /** @inheritDoc **/ | ||
| 326 | override public function renderObjectAt(target:Object, progress:Number, autoRotate:Boolean=false, rotationOffset:Number=0):void { | ||
| 327 | if (progress > 1) { | ||
| 328 | progress -= int(progress); | ||
| 329 | } else if (progress < 0) { | ||
| 330 | progress -= int(progress) - 1; | ||
| 331 | } | ||
| 332 | if (_first == null) { | ||
| 333 | return; | ||
| 334 | } | ||
| 335 | |||
| 336 | var pp:PathPoint = _first; | ||
| 337 | while (pp.next != null && pp.next.progress < progress) { | ||
| 338 | pp = pp.next; | ||
| 339 | } | ||
| 340 | |||
| 341 | if (pp != null) { | ||
| 342 | var pathProg:Number = (progress - pp.progress) / (pp.length / _totalLength); | ||
| 343 | var px:Number = pp.x + pathProg * pp.xChange; | ||
| 344 | var py:Number = pp.y + pathProg * pp.yChange; | ||
| 345 | |||
| 346 | var m:Matrix = this.transform.matrix; | ||
| 347 | target.x = px * m.a + py * m.c + m.tx; | ||
| 348 | target.y = px * m.b + py * m.d + m.ty; | ||
| 349 | |||
| 350 | if (autoRotate) { | ||
| 351 | if (_prevMatrix.a != m.a || _prevMatrix.b != m.b || _prevMatrix.c != m.c || _prevMatrix.d != m.d) { | ||
| 352 | _updateAngles(); | ||
| 353 | } | ||
| 354 | target.rotation = pp.angle + rotationOffset; | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 358 | } | ||
| 359 | |||
| 360 | /** | ||
| 361 | * Translates the progress along a particular segment of the LinePath2D to an overall <code>progress</code> | ||
| 362 | * value, making it easy to position an object like "halfway along the 2nd segment of the line". For example: | ||
| 363 | * <br /><br /><code> | ||
| 364 | * | ||
| 365 | * path.addFollower(mc, path.getSegmentProgress(2, 0.5)); | ||
| 366 | * | ||
| 367 | * </code> | ||
| 368 | * | ||
| 369 | * @param segment The segment number of the line. For example, a line defined by 3 Points would have two segments. | ||
| 370 | * @param progress The <code>progress</code> along the segment. For example, the midpoint of the second segment would be <code>getSegmentProgress(2, 0.5);</code>. | ||
| 371 | * @return The progress value (between 0 and 1) describing the overall progress on the entire LinePath2D. | ||
| 372 | */ | ||
| 373 | public function getSegmentProgress(segment:uint, progress:Number):Number { | ||
| 374 | if (_first == null) { | ||
| 375 | return 0; | ||
| 376 | } else if (_points.length <= segment) { | ||
| 377 | segment = _points.length; | ||
| 378 | } | ||
| 379 | var pp:PathPoint = _points[segment - 1]; | ||
| 380 | return pp.progress + ((progress * pp.length) / _totalLength); | ||
| 381 | } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * Allows you to snap an object like a Sprite, Point, MovieClip, etc. to the LinePath2D by determining | ||
| 385 | * the closest position along the line to the current position of the object. It will automatically | ||
| 386 | * create a PathFollower instance for the target object and reposition it on the LinePath2D. | ||
| 387 | * | ||
| 388 | * @param target The target object that should be repositioned onto the LinePath2D. | ||
| 389 | * @param autoRotate When <code>autoRotate</code> is <code>true</code>, the follower will automatically be rotated so that it is oriented to the angle of the path that it is following. To offset this value (like to always add 90 degrees for example), use the <code>rotationOffset</code> property. | ||
| 390 | * @param rotationOffset When <code>autoRotate</code> is <code>true</code>, this value will always be added to the resulting <code>rotation</code> of the target. | ||
| 391 | * @return A PathFollower instance that was created for the target. | ||
| 392 | */ | ||
| 393 | public function snap(target:Object, autoRotate:Boolean=false, rotationOffset:Number=0):PathFollower { | ||
| 394 | return this.addFollower(target, getClosestProgress(target), autoRotate, rotationOffset); | ||
| 395 | } | ||
| 396 | |||
| 397 | /** | ||
| 398 | * Finds the closest overall <code>progress</code> value on the LinePath2D based on the | ||
| 399 | * target object's current position (<code>x</code> and <code>y</code> properties). For example, | ||
| 400 | * to position the mc object on the LinePath2D at the spot that's closest to the Point x:100, y:50, | ||
| 401 | * you could do:<br /><br /><code> | ||
| 402 | * | ||
| 403 | * path.addFollower(mc, path.getClosestProgress(new Point(100, 50))); | ||
| 404 | * | ||
| 405 | * </code> | ||
| 406 | * | ||
| 407 | * @param target The target object whose position (x/y property values) are analyzed for proximity to the LinePath2D. | ||
| 408 | * @return The overall <code>progress</code> value describing the position on the LinePath2D that is closest to the target's current position. | ||
| 409 | */ | ||
| 410 | public function getClosestProgress(target:Object):Number { | ||
| 411 | if (_first == null || _points.length == 1) { | ||
| 412 | return 0; | ||
| 413 | } | ||
| 414 | |||
| 415 | var closestPath:PathPoint; | ||
| 416 | var closest:Number = 9999999999; | ||
| 417 | var length:Number = 0; | ||
| 418 | var halfPI:Number = Math.PI / 2; | ||
| 419 | |||
| 420 | var xTarg:Number = target.x; | ||
| 421 | var yTarg:Number = target.y; | ||
| 422 | var pp:PathPoint = _first; | ||
| 423 | var dxTarg:Number, dyTarg:Number, dxNext:Number, dyNext:Number, dTarg:Number, angle:Number, next:PathPoint, curDist:Number; | ||
| 424 | while (pp) { | ||
| 425 | dxTarg = xTarg - pp.x; | ||
| 426 | dyTarg = yTarg - pp.y; | ||
| 427 | next = (pp.next != null) ? pp.next : pp; | ||
| 428 | dxNext = next.x - pp.x; | ||
| 429 | dyNext = next.y - pp.y; | ||
| 430 | dTarg = Math.sqrt(dxTarg * dxTarg + dyTarg * dyTarg); | ||
| 431 | |||
| 432 | angle = Math.atan2(dyTarg, dxTarg) - Math.atan2(dyNext, dxNext); | ||
| 433 | if (angle < 0) { | ||
| 434 | angle = -angle; | ||
| 435 | } | ||
| 436 | |||
| 437 | if (angle > halfPI) { //obtuse | ||
| 438 | if (dTarg < closest) { | ||
| 439 | closest = dTarg; | ||
| 440 | closestPath = pp; | ||
| 441 | length = 0; | ||
| 442 | } | ||
| 443 | } else { | ||
| 444 | curDist = Math.cos(angle) * dTarg; | ||
| 445 | if (curDist < 0) { | ||
| 446 | curDist = -curDist; | ||
| 447 | } | ||
| 448 | if (curDist > pp.length) { | ||
| 449 | dxNext = xTarg - next.x; | ||
| 450 | dyNext = yTarg - next.y; | ||
| 451 | curDist = Math.sqrt(dxNext * dxNext + dyNext * dyNext); | ||
| 452 | if (curDist < closest) { | ||
| 453 | closest = curDist; | ||
| 454 | closestPath = pp; | ||
| 455 | length = pp.length; | ||
| 456 | } | ||
| 457 | } else { | ||
| 458 | curDist = Math.sin(angle) * dTarg; | ||
| 459 | if (curDist < closest) { | ||
| 460 | closest = curDist; | ||
| 461 | closestPath = pp; | ||
| 462 | length = Math.cos(angle) * dTarg; | ||
| 463 | } | ||
| 464 | } | ||
| 465 | } | ||
| 466 | pp = pp.next; | ||
| 467 | } | ||
| 468 | |||
| 469 | return closestPath.progress + (length / _totalLength); | ||
| 470 | } | ||
| 471 | |||
| 472 | |||
| 473 | //---- GETTERS / SETTERS ---------------------------------------------------------------------- | ||
| 474 | |||
| 475 | /** Total length of the LinePath2D as though it were stretched out in a straight, flat line. **/ | ||
| 476 | public function get totalLength():Number { | ||
| 477 | return _totalLength; | ||
| 478 | } | ||
| 479 | |||
| 480 | /** The array of Points through which the LinePath2D is drawn. IMPORTANT: Changes to the array are NOT automatically applied or reflected in the LinePath2D - just like the <code>filters</code> property of a DisplayObject, you must set the <code>points</code> property of a LinePath2D directly to ensure that any changes are applied internally. **/ | ||
| 481 | public function get points():Array { | ||
| 482 | var a:Array = []; | ||
| 483 | var l:int = _points.length; | ||
| 484 | for (var i:int = 0; i < l; i++) { | ||
| 485 | a[i] = _points[i].point; | ||
| 486 | } | ||
| 487 | return a; | ||
| 488 | } | ||
| 489 | public function set points(value:Array):void { | ||
| 490 | _points = []; | ||
| 491 | insertMultiplePoints(value, 0); | ||
| 492 | } | ||
| 493 | |||
| 494 | } | ||
| 495 | } | ||
| 496 | import flash.geom.Point; | ||
| 497 | |||
| 498 | internal class PathPoint { | ||
| 499 | public var x:Number; | ||
| 500 | public var y:Number; | ||
| 501 | public var progress:Number; | ||
| 502 | public var xChange:Number; | ||
| 503 | public var yChange:Number; | ||
| 504 | public var point:Point; | ||
| 505 | public var length:Number; | ||
| 506 | public var angle:Number; | ||
| 507 | |||
| 508 | public var next:PathPoint; | ||
| 509 | |||
| 510 | public function PathPoint(point:Point) { | ||
| 511 | this.x = point.x; | ||
| 512 | this.y = point.y; | ||
| 513 | this.point = point; | ||
| 514 | } | ||
| 515 | |||
| 516 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.21 (beta) | ||
| 3 | * DATE: 2010-04-21 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.motionPaths { | ||
| 8 | import flash.display.Shape; | ||
| 9 | import flash.events.Event; | ||
| 10 | /** | ||
| 11 | * A MotionPath defines a path along which a PathFollower can travel, making it relatively simple to do | ||
| 12 | * things like tween an object in a circular path. A PathFollower's position along the path is described using | ||
| 13 | * its <code>progress</code> property, a value between 0 and 1 where 0 is at the beginning of the path, 0.5 is in | ||
| 14 | * the middle, and 1 is at the very end of the path. So to tween a PathFollower along the path, you can simply | ||
| 15 | * tween its <code>progress</code> property. To tween ALL of the followers on the path at once, you can | ||
| 16 | * tween the MotionPath's <code>progress</code> property. PathFollowers automatically wrap so that if | ||
| 17 | * the <code>progress</code> value exceeds 1 or drops below 0, it shows up on the other end of the path.<br /><br /> | ||
| 18 | * | ||
| 19 | * Since MotionPath extends the Shape class, you can add an instance to the display list to see a line representation | ||
| 20 | * of the path drawn which can be helpful especially during the production phase. Use <code>lineStyle()</code> | ||
| 21 | * to adjust the color, thickness, and other attributes of the line that is drawn (or set the MotionPath's | ||
| 22 | * <code>visible</code> property to false or don't add it to the display list if you don't want to see the line | ||
| 23 | * at all). You can also adjust all of its properties like <code>scaleX, scaleY, rotation, width, height, x,</code> | ||
| 24 | * and <code>y</code> just like any DisplayObject. That means you can tween those values as well to achieve very | ||
| 25 | * dynamic, complex effects with ease.<br /><br /> | ||
| 26 | * | ||
| 27 | * @example Example AS3 code:<listing version="3.0"> | ||
| 28 | import com.greensock.~~; | ||
| 29 | import com.greensock.plugins.~~; | ||
| 30 | import com.greensock.motionPaths.~~; | ||
| 31 | TweenPlugin.activate([CirclePath2DPlugin]); //only needed once in your swf, and only if you plan to use the circlePath2D tweening feature for convenience | ||
| 32 | |||
| 33 | //create a circle motion path at coordinates x:150, y:150 with a radius of 100 | ||
| 34 | var circle:CirclePath2D = new CirclePath2D(150, 150, 100); | ||
| 35 | |||
| 36 | //tween mc along the path from the bottom (90 degrees) to 315 degrees in the counter-clockwise direction and make an extra revolution | ||
| 37 | TweenLite.to(mc, 3, {circlePath2D:{path:circle, startAngle:90, endAngle:315, autoRotate:true, direction:Direction.COUNTER_CLOCKWISE, extraRevolutions:1}}); | ||
| 38 | |||
| 39 | //tween the circle's rotation, scaleX, scaleY, x, and y properties: | ||
| 40 | TweenLite.to(circle, 3, {rotation:180, scaleX:0.5, scaleY:2, x:250, y:200}); | ||
| 41 | |||
| 42 | //show the path visually by adding it to the display list (optional) | ||
| 43 | this.addChild(circle); | ||
| 44 | |||
| 45 | |||
| 46 | //--- Instead of using the plugin, you could manually manage followers and tween their "progress" property... | ||
| 47 | |||
| 48 | //make the MovieClip "mc2" follow the circle and start at a position of 90 degrees (this returns a PathFollower instance) | ||
| 49 | var follower:PathFollower = circle.addFollower(mc2, circle.angleToProgress(90)); | ||
| 50 | |||
| 51 | //tween the follower clockwise along the path to 315 degrees | ||
| 52 | TweenLite.to(follower, 2, {progress:circle.followerTween(follower, 315, Direction.CLOCKWISE)}); | ||
| 53 | |||
| 54 | //tween the follower counter-clockwise to 200 degrees and add an extra revolution | ||
| 55 | TweenLite.to(follower, 2, {progress:circle.followerTween(follower, 200, Direction.COUNTER_CLOCKWISE, 1)}); | ||
| 56 | </listing> | ||
| 57 | * | ||
| 58 | * <b>NOTES</b><br /> | ||
| 59 | * <ul> | ||
| 60 | * <li>All followers are automatically updated when you alter the MotionPath that they're following.</li> | ||
| 61 | * <li>To tween all followers along the path at once, simply tween the MotionPath's <code>progress</code> | ||
| 62 | * property which will provide better performance than tweening each follower independently.</li> | ||
| 63 | * </ul> | ||
| 64 | * | ||
| 65 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 66 | * | ||
| 67 | * @author Jack Doyle, jack@greensock.com | ||
| 68 | */ | ||
| 69 | public class MotionPath extends Shape { | ||
| 70 | /** @private **/ | ||
| 71 | protected static const _RAD2DEG:Number = 180 / Math.PI; | ||
| 72 | /** @private **/ | ||
| 73 | protected static const _DEG2RAD:Number = Math.PI / 180; | ||
| 74 | |||
| 75 | /** @private **/ | ||
| 76 | protected var _redrawLine:Boolean; | ||
| 77 | |||
| 78 | /** @private **/ | ||
| 79 | protected var _thickness:Number; | ||
| 80 | /** @private **/ | ||
| 81 | protected var _color:uint; | ||
| 82 | /** @private **/ | ||
| 83 | protected var _lineAlpha:Number; | ||
| 84 | /** @private **/ | ||
| 85 | protected var _pixelHinting:Boolean; | ||
| 86 | /** @private **/ | ||
| 87 | protected var _scaleMode:String; | ||
| 88 | /** @private **/ | ||
| 89 | protected var _caps:String; | ||
| 90 | /** @private **/ | ||
| 91 | protected var _joints:String; | ||
| 92 | /** @private **/ | ||
| 93 | protected var _miterLimit:Number; | ||
| 94 | |||
| 95 | /** @private **/ | ||
| 96 | protected var _rootFollower:PathFollower; | ||
| 97 | /** @private **/ | ||
| 98 | protected var _progress:Number; | ||
| 99 | |||
| 100 | /** @private **/ | ||
| 101 | public function MotionPath() { | ||
| 102 | _progress = 0; | ||
| 103 | lineStyle(1, 0x666666, 1, false, "none", null, null, 3, true); | ||
| 104 | this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true); | ||
| 105 | } | ||
| 106 | |||
| 107 | /** @private **/ | ||
| 108 | protected function onAddedToStage(event:Event):void { | ||
| 109 | renderAll(); | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Adds a follower to the path, optionally setting it to a particular progress position. If | ||
| 114 | * the target isn't a PathFollower instance already, one will be created for it. The target | ||
| 115 | * can be any object that has x and y properties. | ||
| 116 | * | ||
| 117 | * @param target Any object that has x and y properties that you'd like to follow the path. Existing PathFollower instances are allowed. | ||
| 118 | * @param progress The progress position at which the target should be placed initially (0 by default) | ||
| 119 | * @param autoRotate When <code>autoRotate</code> is <code>true</code>, the target will automatically be rotated so that it is oriented to the angle of the path. To offset this value (like to always add 90 degrees for example), use the <code>rotationOffset</code> property. | ||
| 120 | * @param rotationOffset When <code>autoRotate</code> is <code>true</code>, this value will always be added to the resulting <code>rotation</code> of the target. | ||
| 121 | * @return A PathFollower instance associated with the target (you can tween this PathFollower's <code>progress</code> property to move it along the path). | ||
| 122 | */ | ||
| 123 | public function addFollower(target:*, progress:Number=0, autoRotate:Boolean=false, rotationOffset:Number=0):PathFollower { | ||
| 124 | var f:PathFollower = getFollower(target); | ||
| 125 | if (f == null) { | ||
| 126 | f = new PathFollower(target); | ||
| 127 | } | ||
| 128 | f.autoRotate = autoRotate; | ||
| 129 | f.rotationOffset = rotationOffset; | ||
| 130 | if (f.path != this) { | ||
| 131 | if (_rootFollower) { | ||
| 132 | _rootFollower.cachedPrev = f; | ||
| 133 | } | ||
| 134 | f.cachedNext = _rootFollower; | ||
| 135 | _rootFollower = f; | ||
| 136 | f.path = this; | ||
| 137 | f.cachedProgress = progress; | ||
| 138 | renderObjectAt(f.target, progress, autoRotate, rotationOffset); | ||
| 139 | } | ||
| 140 | return f; | ||
| 141 | } | ||
| 142 | |||
| 143 | /** | ||
| 144 | * Removes the target as a follower. The target can be a PathFollower instance or the target associated | ||
| 145 | * with one of the PathFollower instances. | ||
| 146 | * | ||
| 147 | * @param target the target or PathFollower instance to remove. | ||
| 148 | */ | ||
| 149 | public function removeFollower(target:*):void { | ||
| 150 | var f:PathFollower = getFollower(target); | ||
| 151 | if (f == null) { | ||
| 152 | return; | ||
| 153 | } | ||
| 154 | if (f.cachedNext) { | ||
| 155 | f.cachedNext.cachedPrev = f.cachedPrev; | ||
| 156 | } | ||
| 157 | if (f.cachedPrev) { | ||
| 158 | f.cachedPrev.cachedNext = f.cachedNext; | ||
| 159 | } else if (_rootFollower == f) { | ||
| 160 | _rootFollower = null; | ||
| 161 | } | ||
| 162 | f.cachedNext = f.cachedPrev = null; | ||
| 163 | f.path = null; | ||
| 164 | } | ||
| 165 | |||
| 166 | /** Removes all followers. **/ | ||
| 167 | public function removeAllFollowers():void { | ||
| 168 | var f:PathFollower = _rootFollower; | ||
| 169 | var next:PathFollower; | ||
| 170 | while (f) { | ||
| 171 | next = f.cachedNext; | ||
| 172 | f.cachedNext = f.cachedPrev = null; | ||
| 173 | f.path = null; | ||
| 174 | f = next; | ||
| 175 | } | ||
| 176 | _rootFollower = null; | ||
| 177 | } | ||
| 178 | |||
| 179 | /** | ||
| 180 | * Distributes objects evenly along the MotionPath. You can optionally define minimum and maximum | ||
| 181 | * <code>progress</code> values between which the objects will be distributed. For example, if you want them | ||
| 182 | * distributed from the very beginning of the path to the middle, you would do:<br /><br /><code> | ||
| 183 | * | ||
| 184 | * path.distribute([mc1, mc2, mc3], 0, 0.5);<br /><br /></code> | ||
| 185 | * | ||
| 186 | * As it loops through the <code>targets</code> array, if a target is found for which a PathFollower | ||
| 187 | * doesn't exist, one will automatically be created and added to the path. The <code>targets</code> | ||
| 188 | * array can be populated with PathFollowers or DisplayObjects or Points or pretty much any object. | ||
| 189 | * | ||
| 190 | * @param targets An array of targets (PathFollowers, DisplayObjects, Points, or pretty much any object) that should be distributed evenly along the MotionPath. As it loops through the <code>targets</code> array, if a target is found for which a PathFollower doesn't exist, one will automatically be created and added to the path. | ||
| 191 | * @param min The minimum <code>progress</code> value at which the targets will begin being distributed. This value will always be between 0 and 1. For example, if the targets should be distributed from the midpoint of the path through the end, the <code>min</code> parameter would be 0.5 and the <code>max</code> parameter would be 1. | ||
| 192 | * @param max The maximum <code>progress</code> value where the targets will end distribution. This value will always be between 0 and 1. For example, if the targets should be distributed from the midpoint of the path through the end, the <code>min</code> parameter would be 0.5 and the <code>max</code> parameter would be 1. | ||
| 193 | * @param autoRotate When <code>autoRotate</code> is <code>true</code>, the target will automatically be rotated so that it is oriented to the angle of the path. To offset this value (like to always add 90 degrees for example), use the <code>rotationOffset</code> property. | ||
| 194 | * @param rotationOffset When <code>autoRotate</code> is <code>true</code>, this value will always be added to the resulting <code>rotation</code> of the target. For example, to always add 90 degrees to the autoRotation, <code>rotationOffset</code> would be 90. | ||
| 195 | */ | ||
| 196 | public function distribute(targets:Array=null, min:Number=0, max:Number=1, autoRotate:Boolean=false, rotationOffset:Number=0):void { | ||
| 197 | if (targets == null) { | ||
| 198 | targets = this.followers; | ||
| 199 | } | ||
| 200 | min = _normalize(min); | ||
| 201 | max = _normalize(max); | ||
| 202 | var f:PathFollower; | ||
| 203 | var i:int = targets.length; | ||
| 204 | var space:Number = (i > 1) ? (max - min) / (i - 1) : 1; | ||
| 205 | while (--i > -1) { | ||
| 206 | f = getFollower(targets[i]); | ||
| 207 | if (f == null) { | ||
| 208 | f = this.addFollower(targets[i], 0, autoRotate, rotationOffset); | ||
| 209 | } | ||
| 210 | f.cachedProgress = min + (space * i); | ||
| 211 | this.renderObjectAt(f.target, f.cachedProgress, autoRotate, rotationOffset); | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | /** @private **/ | ||
| 216 | protected function _normalize(num:Number):Number { | ||
| 217 | if (num > 1) { | ||
| 218 | num -= int(num); | ||
| 219 | } else if (num < 0) { | ||
| 220 | num -= int(num) - 1; | ||
| 221 | } | ||
| 222 | return num; | ||
| 223 | } | ||
| 224 | |||
| 225 | /** | ||
| 226 | * Returns the PathFollower instance associated with a particular target or null if none exists. | ||
| 227 | * | ||
| 228 | * @param target The target whose PathFollower instance you want returned. | ||
| 229 | * @return PathFollower instance | ||
| 230 | */ | ||
| 231 | public function getFollower(target:Object):PathFollower { | ||
| 232 | if (target is PathFollower) { | ||
| 233 | return target as PathFollower; | ||
| 234 | } | ||
| 235 | var f:PathFollower = _rootFollower; | ||
| 236 | while (f) { | ||
| 237 | if (f.target == target) { | ||
| 238 | return f; | ||
| 239 | } | ||
| 240 | f = f.cachedNext; | ||
| 241 | } | ||
| 242 | return null; | ||
| 243 | } | ||
| 244 | |||
| 245 | /** @private **/ | ||
| 246 | protected function renderAll():void { | ||
| 247 | |||
| 248 | } | ||
| 249 | |||
| 250 | /** | ||
| 251 | * Positions any object with x and y properties on the path at a specific progress position. | ||
| 252 | * For example, to position <code>mc</code> in the middle of the path, you would do:<br /><br /><code> | ||
| 253 | * | ||
| 254 | * myPath.renderObjectAt(mc, 0.5);</code><br /><br /> | ||
| 255 | * | ||
| 256 | * Some paths have methods to translate other meaningful information into a progress value, like | ||
| 257 | * for a <code>CirclePath2D</code> you can get the progress associated with the 90-degree position with the | ||
| 258 | * <code>angleToPosition()</code> method like this:<br /><br /><code> | ||
| 259 | * | ||
| 260 | * myCircle.renderObjectAt(mc, myCircle.angleToProgress(90)); | ||
| 261 | * | ||
| 262 | * </code><br /> | ||
| 263 | * | ||
| 264 | * @param target The target object to position | ||
| 265 | * @param progress The progress value (typically between 0 and 1 where 0 is the beginning of the path, 0.5 is in the middle, and 1 is at the end) | ||
| 266 | * @param autoRotate When <code>autoRotate</code> is <code>true</code>, the target will automatically be rotated so that it is oriented to the angle of the path. To offset this value (like to always add 90 degrees for example), use the <code>rotationOffset</code> property. | ||
| 267 | * @param rotationOffset When <code>autoRotate</code> is <code>true</code>, this value will always be added to the resulting <code>rotation</code> of the target. | ||
| 268 | */ | ||
| 269 | public function renderObjectAt(target:Object, progress:Number, autoRotate:Boolean=false, rotationOffset:Number=0):void { | ||
| 270 | |||
| 271 | } | ||
| 272 | |||
| 273 | /** | ||
| 274 | * Sets the line style for the path which you will only see if you add the path to the display list | ||
| 275 | * with something like addChild() and make sure the visible property is true. For example, to make | ||
| 276 | * a CirclePath2D visible with a red line red that's 3 pixels thick, you could do: <br /><br /><code> | ||
| 277 | * | ||
| 278 | * var myCircle:CirclePath2D = new CirclePath2D(150, 150, 100); <br /> | ||
| 279 | * myCircle.lineStyle(3, 0xFF0000);<br /> | ||
| 280 | * addChild(myCircle);<br /> | ||
| 281 | * | ||
| 282 | * </code> | ||
| 283 | * | ||
| 284 | * @param thickness line thickness | ||
| 285 | * @param color line color | ||
| 286 | * @param alpha line alpha | ||
| 287 | * @param pixelHinting pixel hinting | ||
| 288 | * @param scaleMode scale mode | ||
| 289 | * @param caps caps | ||
| 290 | * @param joints joints | ||
| 291 | * @param miterLimit miter limit | ||
| 292 | * @param skipRedraw if true, the redraw will be skipped. | ||
| 293 | */ | ||
| 294 | public function lineStyle(thickness:Number=1, color:uint=0x666666, alpha:Number=1, pixelHinting:Boolean=false, scaleMode:String="none", caps:String=null, joints:String=null, miterLimit:Number=3, skipRedraw:Boolean=false):void { | ||
| 295 | _thickness = thickness; | ||
| 296 | _color = color; | ||
| 297 | _lineAlpha = alpha; | ||
| 298 | _pixelHinting = pixelHinting; | ||
| 299 | _scaleMode = scaleMode; | ||
| 300 | _caps = caps; | ||
| 301 | _joints = joints; | ||
| 302 | _miterLimit = miterLimit; | ||
| 303 | _redrawLine = true; | ||
| 304 | if (!skipRedraw) { | ||
| 305 | renderAll(); | ||
| 306 | } | ||
| 307 | } | ||
| 308 | |||
| 309 | /** @inheritDoc **/ | ||
| 310 | override public function get rotation():Number { | ||
| 311 | return super.rotation; | ||
| 312 | } | ||
| 313 | override public function set rotation(value:Number):void { | ||
| 314 | super.rotation = value; | ||
| 315 | renderAll(); | ||
| 316 | } | ||
| 317 | |||
| 318 | /** @inheritDoc **/ | ||
| 319 | override public function get scaleX():Number { | ||
| 320 | return super.scaleX; | ||
| 321 | } | ||
| 322 | override public function set scaleX(value:Number):void { | ||
| 323 | super.scaleX = value; | ||
| 324 | renderAll(); | ||
| 325 | } | ||
| 326 | |||
| 327 | /** @inheritDoc **/ | ||
| 328 | override public function get scaleY():Number { | ||
| 329 | return super.scaleY; | ||
| 330 | } | ||
| 331 | override public function set scaleY(value:Number):void { | ||
| 332 | super.scaleY = value; | ||
| 333 | renderAll(); | ||
| 334 | } | ||
| 335 | |||
| 336 | /** @inheritDoc **/ | ||
| 337 | override public function get x():Number { | ||
| 338 | return super.x; | ||
| 339 | } | ||
| 340 | override public function set x(value:Number):void { | ||
| 341 | super.x = value; | ||
| 342 | renderAll(); | ||
| 343 | } | ||
| 344 | |||
| 345 | /** @inheritDoc **/ | ||
| 346 | override public function get y():Number { | ||
| 347 | return super.y; | ||
| 348 | } | ||
| 349 | override public function set y(value:Number):void { | ||
| 350 | super.y = value; | ||
| 351 | renderAll(); | ||
| 352 | } | ||
| 353 | |||
| 354 | /** @inheritDoc **/ | ||
| 355 | override public function get width():Number { | ||
| 356 | return super.width; | ||
| 357 | } | ||
| 358 | override public function set width(value:Number):void { | ||
| 359 | super.width = value; | ||
| 360 | renderAll(); | ||
| 361 | } | ||
| 362 | |||
| 363 | /** @inheritDoc **/ | ||
| 364 | override public function get height():Number { | ||
| 365 | return super.height; | ||
| 366 | } | ||
| 367 | override public function set height(value:Number):void { | ||
| 368 | super.height = value; | ||
| 369 | renderAll(); | ||
| 370 | } | ||
| 371 | |||
| 372 | /** @inheritDoc **/ | ||
| 373 | override public function get visible():Boolean { | ||
| 374 | return super.visible; | ||
| 375 | } | ||
| 376 | override public function set visible(value:Boolean):void { | ||
| 377 | super.visible = value; | ||
| 378 | _redrawLine = true; | ||
| 379 | renderAll(); | ||
| 380 | } | ||
| 381 | |||
| 382 | /** | ||
| 383 | * A value (typically between 0 and 1) that can be used to move all followers along the path. Unlike a PathFollower's | ||
| 384 | * <code>progress</code>, this value is not absolute - it simply facilitates movement of followers together along the | ||
| 385 | * path in a way that performs better than tweening each follower independently (plus it's easier). You can tween to | ||
| 386 | * values that are greater than 1 or less than 0 but the values are simply wrapped. So, for example, setting | ||
| 387 | * <code>progress</code> to 1.2 is the same as setting it to 0.2 and -0.2 is the same as 0.8. If your goal is to | ||
| 388 | * tween all followers around a CirclePath2D twice completely, you could just add 2 to the progress value or use a | ||
| 389 | * relative value in the tween, like: <br /><br /><code> | ||
| 390 | * | ||
| 391 | * TweenLite.to(myCircle, 5, {progress:"2"}); //or myCircle.progress + 2 | ||
| 392 | * | ||
| 393 | * </code> | ||
| 394 | **/ | ||
| 395 | public function get progress():Number { | ||
| 396 | return _progress; | ||
| 397 | } | ||
| 398 | public function set progress(value:Number):void { | ||
| 399 | if (value > 1) { | ||
| 400 | value -= int(value); | ||
| 401 | } else if (value < 0) { | ||
| 402 | value -= int(value) - 1; | ||
| 403 | } | ||
| 404 | var dif:Number = value - _progress; | ||
| 405 | var f:PathFollower = _rootFollower; | ||
| 406 | while (f) { | ||
| 407 | f.cachedProgress += dif; | ||
| 408 | |||
| 409 | if (f.cachedProgress > 1) { | ||
| 410 | f.cachedProgress -= int(f.cachedProgress); | ||
| 411 | } else if (f.cachedProgress < 0) { | ||
| 412 | f.cachedProgress -= int(f.cachedProgress) - 1; | ||
| 413 | } | ||
| 414 | |||
| 415 | f = f.cachedNext; | ||
| 416 | } | ||
| 417 | _progress = value; | ||
| 418 | renderAll(); | ||
| 419 | } | ||
| 420 | |||
| 421 | /** Returns an array of all PathFollower instances associated with this path **/ | ||
| 422 | public function get followers():Array { | ||
| 423 | var a:Array = []; | ||
| 424 | var cnt:uint = 0; | ||
| 425 | var f:PathFollower = _rootFollower; | ||
| 426 | while (f) { | ||
| 427 | a[cnt++] = f; | ||
| 428 | f = f.cachedNext; | ||
| 429 | } | ||
| 430 | return a; | ||
| 431 | } | ||
| 432 | |||
| 433 | /** Returns an array of all target instances associated with the PathFollowers of this path **/ | ||
| 434 | public function get targets():Array { | ||
| 435 | var a:Array = []; | ||
| 436 | var cnt:uint = 0; | ||
| 437 | var f:PathFollower = _rootFollower; | ||
| 438 | while (f) { | ||
| 439 | a[cnt++] = f.target; | ||
| 440 | f = f.cachedNext; | ||
| 441 | } | ||
| 442 | return a; | ||
| 443 | } | ||
| 444 | |||
| 445 | } | ||
| 446 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.2 (beta) | ||
| 3 | * DATE: 2010-04-21 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.motionPaths { | ||
| 8 | /** | ||
| 9 | * A PathFollower is used to associate a particular target object (like a MovieClip, Point, Sprite, etc.) | ||
| 10 | * with a MotionPath and it offers a tweenable <code>progress</code> property that manages positioning | ||
| 11 | * the target on the path accordingly. The <code>progress</code> property is a value between | ||
| 12 | * 0 and 1 where 0 is at the beginning of the path, 0.5 is in the middle, and 1 is at the end. | ||
| 13 | * When the follower's <code>autoRotate</code> property is <code>true</code>, the target will be | ||
| 14 | * rotated in relation to the path that it is following. <br /><br /> | ||
| 15 | * | ||
| 16 | * @example Example AS3 code:<listing version="3.0"> | ||
| 17 | import com.greensock.~~; | ||
| 18 | import com.greensock.motionPaths.~~; | ||
| 19 | |||
| 20 | //create a circle motion path at coordinates x:150, y:150 with a radius of 100 | ||
| 21 | var circle:Circle2D = new Circle2D(150, 150, 100); | ||
| 22 | |||
| 23 | //make the MovieClip "mc" follow the circle and start at a position of 90 degrees (this returns a PathFollower instance) | ||
| 24 | var follower:PathFollower = circle.addFollower(mc, circle.angleToProgress(90), true); | ||
| 25 | |||
| 26 | //tween the follower clockwise along the path to 315 degrees | ||
| 27 | TweenLite.to(follower, 2, {progress:circle.followerTween(follower, 315, Direction.CLOCKWISE)}); | ||
| 28 | |||
| 29 | //tween the follower counter-clockwise to 200 degrees and add an extra revolution | ||
| 30 | TweenLite.to(follower, 2, {progress:circle.followerTween(follower, 200, Direction.COUNTER_CLOCKWISE, 1)}); | ||
| 31 | </listing> | ||
| 32 | * | ||
| 33 | * <b>NOTES</b><br /> | ||
| 34 | * <ul> | ||
| 35 | * <li>All followers are automatically updated when you alter the MotionPath that they're following.</li> | ||
| 36 | * <li>To tween all followers along the path at once, simply tween the MotionPath's <code>progress</code> | ||
| 37 | * property which will provide better performance than tweening each follower independently.</li> | ||
| 38 | * </ul> | ||
| 39 | * | ||
| 40 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 41 | * | ||
| 42 | * @author Jack Doyle, jack@greensock.com | ||
| 43 | */ | ||
| 44 | public class PathFollower { | ||
| 45 | /** The target object associated with the PathFollower (like a Sprite, MovieClip, Point, etc.). The object must have x and y properties. **/ | ||
| 46 | public var target:Object; | ||
| 47 | |||
| 48 | /** @private **/ | ||
| 49 | public var cachedProgress:Number; | ||
| 50 | /** @private **/ | ||
| 51 | public var cachedNext:PathFollower; | ||
| 52 | /** @private **/ | ||
| 53 | public var cachedPrev:PathFollower; | ||
| 54 | |||
| 55 | /** The MotionPath instance that this PathFollower should follow **/ | ||
| 56 | public var path:MotionPath; | ||
| 57 | /** When <code>autoRotate</code> is <code>true</code>, the follower will automatically be rotated so that it is oriented to the angle of the path that it is following. To offset this value (like to always add 90 degrees for example), use the <code>rotationOffset</code> property. **/ | ||
| 58 | public var autoRotate:Boolean; | ||
| 59 | /** When <code>autoRotate</code> is <code>true</code>, this value will always be added to the resulting <code>rotation</code> of the target. **/ | ||
| 60 | public var rotationOffset:Number; | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Constructor | ||
| 64 | * | ||
| 65 | * @param target The target object associated with the PathFollower (like a Sprite, MovieClip, Point, etc.). The object must have x and y properties. | ||
| 66 | * @param autoRotate When <code>autoRotate</code> is <code>true</code>, the follower will automatically be rotated so that it is oriented to the angle of the path that it is following. To offset this value (like to always add 90 degrees for example), use the <code>rotationOffset</code> property. | ||
| 67 | * @param rotationOffset When <code>autoRotate</code> is <code>true</code>, this value will always be added to the resulting <code>rotation</code> of the target. | ||
| 68 | */ | ||
| 69 | public function PathFollower(target:Object, autoRotate:Boolean=false, rotationOffset:Number=0) { | ||
| 70 | this.target = target; | ||
| 71 | this.autoRotate = autoRotate; | ||
| 72 | this.rotationOffset = rotationOffset; | ||
| 73 | this.cachedProgress = 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | /** | ||
| 77 | * A value (typically between 0 and 1) that can be used to move all followers along the path. You can tween to | ||
| 78 | * values that are greater than 1 or less than 0 but the values are simply wrapped. So, for example, setting | ||
| 79 | * <code>progress</code> to 1.2 is the same as setting it to 0.2 and -0.2 is the same as 0.8. If your goal is to | ||
| 80 | * tween the PathFollower around a Circle2D twice completely, you could just add 2 to the <code>progress</code> | ||
| 81 | * value or use a relative value in the tween, like: <br /><br /><code> | ||
| 82 | * | ||
| 83 | * TweenLite.to(myFollower, 5, {progress:"2"}); //or myFollower.progress + 2 | ||
| 84 | * | ||
| 85 | * </code> | ||
| 86 | **/ | ||
| 87 | public function get progress():Number { | ||
| 88 | return this.cachedProgress; | ||
| 89 | } | ||
| 90 | public function set progress(value:Number):void { | ||
| 91 | if (value > 1) { | ||
| 92 | value -= int(value); | ||
| 93 | } else if (value < 0) { | ||
| 94 | value -= int(value) - 1; | ||
| 95 | } | ||
| 96 | this.cachedProgress = value; | ||
| 97 | if (this.path) { | ||
| 98 | this.path.renderObjectAt(this.target, value, this.autoRotate, this.rotationOffset); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | } | ||
| 103 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.2 (beta) | ||
| 3 | * DATE: 2010-04-21 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.motionPaths { | ||
| 8 | import flash.display.Graphics; | ||
| 9 | import flash.geom.Matrix; | ||
| 10 | /** | ||
| 11 | * A RectanglePath2D defines a rectangular path on which a PathFollower can be placed, making it simple to tween objects | ||
| 12 | * along a rectangle's perimeter. A PathFollower's position along the path is described using its <code>progress</code> property, | ||
| 13 | * a value between 0 and 1 where 0 is at the beginning of the path (top left corner), and as the value increases, it | ||
| 14 | * moves clockwise along the path so that 0.5 would be at the lower right corner, and 1 is all the way back at the | ||
| 15 | * upper left corner of the path. So to tween a PathFollower along the path, you can simply tween its | ||
| 16 | * <code>progress</code> property. To tween ALL of the followers on the path at once, you can tween the | ||
| 17 | * RectanglePath2D's <code>progress</code> property. PathFollowers automatically wrap so that if the <code>progress</code> | ||
| 18 | * value exceeds 1 it continues at the beginning of the path.<br /><br /> | ||
| 19 | * | ||
| 20 | * Since RectanglePath2D extends the Shape class, you can add an instance to the display list to see a line representation | ||
| 21 | * of the path drawn which can be helpful especially during the production phase. Use <code>lineStyle()</code> | ||
| 22 | * to adjust the color, thickness, and other attributes of the line that is drawn (or set the RectanglePath2D's | ||
| 23 | * <code>visible</code> property to false or don't add it to the display list if you don't want to see the line | ||
| 24 | * at all). You can also adjust all of its properties like <code>scaleX, scaleY, rotation, width, height, x,</code> | ||
| 25 | * and <code>y</code>. That means you can tween those values as well to achieve very dynamic, complex effects | ||
| 26 | * with ease.<br /><br /> | ||
| 27 | * | ||
| 28 | * @example Example AS3 code:<listing version="3.0"> | ||
| 29 | import com.greensock.~~; | ||
| 30 | import com.greensock.motionPaths.~~; | ||
| 31 | |||
| 32 | //create a rectangular motion path at coordinates x:25, y:25 with a width of 150 and a height of 100 | ||
| 33 | var rect:RectanglePath2D = new RectanglePath2D(25, 25, 150, 100, false); | ||
| 34 | |||
| 35 | //position the MovieClip "mc" at the beginning of the path (upper left corner), and reference the resulting PathFollower instance with a "follower" variable. | ||
| 36 | var follower:PathFollower = rect.addFollower(mc, 0); | ||
| 37 | |||
| 38 | //tween the follower clockwise along the path all the way to the end, one full revolution | ||
| 39 | TweenLite.to(follower, 2, {progress:1}); | ||
| 40 | |||
| 41 | //tween the follower counter-clockwise by using a negative progress value | ||
| 42 | TweenLite.to(follower, 2, {progress:-1}); | ||
| 43 | </listing> | ||
| 44 | * | ||
| 45 | * <b>NOTES</b><br /> | ||
| 46 | * <ul> | ||
| 47 | * <li>All followers' positions are automatically updated when you alter the MotionPath that they're following.</li> | ||
| 48 | * <li>To tween all followers along the path at once, simply tween the MotionPath's <code>progress</code> | ||
| 49 | * property which will provide better performance than tweening each follower independently.</li> | ||
| 50 | * </ul> | ||
| 51 | * | ||
| 52 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 53 | * | ||
| 54 | * @author Jack Doyle, jack@greensock.com | ||
| 55 | */ | ||
| 56 | public class RectanglePath2D extends MotionPath { | ||
| 57 | /** @private **/ | ||
| 58 | protected var _rawWidth:Number; | ||
| 59 | /** @private **/ | ||
| 60 | protected var _rawHeight:Number; | ||
| 61 | /** @private **/ | ||
| 62 | protected var _centerOrigin:Boolean; | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Constructor | ||
| 66 | * | ||
| 67 | * @param x The x coordinate of the origin of the rectangle (typically its top left corner unless <code>centerOrigin</code> is <code>true</code>) | ||
| 68 | * @param y The y coordinate of the origin of the rectangle (typically its top left corner unless <code>centerOrigin</code> is <code>true</code>) | ||
| 69 | * @param rawWidth The width of the rectangle in its unrotated and unscaled state | ||
| 70 | * @param rawHeight The height of the rectangle in its unrotated and unscaled state | ||
| 71 | * @param centerOrigin To position the origin (registration point around which transformations occur) at the center of the rectangle instead of its upper left corner, set <code>centerOrigin</code> to <code>true</code> (it is false by default). | ||
| 72 | */ | ||
| 73 | public function RectanglePath2D(x:Number, y:Number, rawWidth:Number, rawHeight:Number, centerOrigin:Boolean=false) { | ||
| 74 | super(); | ||
| 75 | _rawWidth = rawWidth; | ||
| 76 | _rawHeight = rawHeight; | ||
| 77 | _centerOrigin = centerOrigin; | ||
| 78 | super.x = x; | ||
| 79 | super.y = y; | ||
| 80 | } | ||
| 81 | |||
| 82 | /** @private **/ | ||
| 83 | override protected function renderAll():void { | ||
| 84 | var xOffset:Number = _centerOrigin ? _rawWidth / -2 : 0; | ||
| 85 | var yOffset:Number = _centerOrigin ? _rawHeight / -2 : 0; | ||
| 86 | |||
| 87 | var length:Number, px:Number, py:Number, xFactor:Number, yFactor:Number; | ||
| 88 | var m:Matrix = this.transform.matrix; | ||
| 89 | var a:Number = m.a, b:Number = m.b, c:Number = m.c, d:Number = m.d, tx:Number = m.tx, ty:Number = m.ty; | ||
| 90 | var f:PathFollower = _rootFollower; | ||
| 91 | while (f) { | ||
| 92 | px = xOffset; | ||
| 93 | py = yOffset; | ||
| 94 | if (f.cachedProgress < 0.5) { | ||
| 95 | length = f.cachedProgress * (_rawWidth + _rawHeight) * 2; | ||
| 96 | if (length > _rawWidth) { //top | ||
| 97 | px += _rawWidth; | ||
| 98 | py += length - _rawWidth; | ||
| 99 | xFactor = 0; | ||
| 100 | yFactor = _rawHeight; | ||
| 101 | } else { //right | ||
| 102 | px += length; | ||
| 103 | xFactor = _rawWidth; | ||
| 104 | yFactor = 0; | ||
| 105 | } | ||
| 106 | } else { | ||
| 107 | length = (f.cachedProgress - 0.5) / 0.5 * (_rawWidth + _rawHeight); | ||
| 108 | if (length <= _rawWidth) { //bottom | ||
| 109 | px += _rawWidth - length; | ||
| 110 | py += _rawHeight; | ||
| 111 | xFactor = -_rawWidth; | ||
| 112 | yFactor = 0; | ||
| 113 | } else { //left | ||
| 114 | py += _rawHeight - (length - _rawWidth); | ||
| 115 | xFactor = 0; | ||
| 116 | yFactor = -_rawHeight; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | f.target.x = px * a + py * c + tx; | ||
| 121 | f.target.y = px * b + py * d + ty; | ||
| 122 | |||
| 123 | if (f.autoRotate) { | ||
| 124 | f.target.rotation = Math.atan2(xFactor * b + yFactor * d, xFactor * a + yFactor * c) * _RAD2DEG + f.rotationOffset; | ||
| 125 | } | ||
| 126 | |||
| 127 | f = f.cachedNext; | ||
| 128 | } | ||
| 129 | if (_redrawLine && this.visible && this.parent) { | ||
| 130 | var g:Graphics = this.graphics; | ||
| 131 | g.clear(); | ||
| 132 | g.lineStyle(_thickness, _color, _lineAlpha, _pixelHinting, _scaleMode, _caps, _joints, _miterLimit); | ||
| 133 | g.drawRect(xOffset, yOffset, _rawWidth, _rawHeight); | ||
| 134 | _redrawLine = false; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | /** @inheritDoc **/ | ||
| 139 | override public function renderObjectAt(target:Object, progress:Number, autoRotate:Boolean=false, rotationOffset:Number=0):void { | ||
| 140 | if (progress > 1) { | ||
| 141 | progress -= int(progress); | ||
| 142 | } else if (progress < 0) { | ||
| 143 | progress -= int(progress) - 1; | ||
| 144 | } | ||
| 145 | |||
| 146 | var px:Number = _centerOrigin ? _rawWidth / -2 : 0; | ||
| 147 | var py:Number = _centerOrigin ? _rawHeight / -2 : 0; | ||
| 148 | var length:Number, xFactor:Number, yFactor:Number; | ||
| 149 | if (progress < 0.5) { | ||
| 150 | length = progress * (_rawWidth + _rawHeight) * 2; | ||
| 151 | if (length > _rawWidth) { | ||
| 152 | px += _rawWidth; | ||
| 153 | py += length - _rawWidth; | ||
| 154 | xFactor = 0; | ||
| 155 | yFactor = _rawHeight; | ||
| 156 | } else { | ||
| 157 | px += length; | ||
| 158 | xFactor = _rawWidth; | ||
| 159 | yFactor = 0; | ||
| 160 | } | ||
| 161 | } else { | ||
| 162 | length = (progress - 0.5) / 0.5 * (_rawWidth + _rawHeight); | ||
| 163 | if (length <= _rawWidth) { | ||
| 164 | px += _rawWidth - length; | ||
| 165 | py += _rawHeight; | ||
| 166 | xFactor = -_rawWidth; | ||
| 167 | yFactor = 0; | ||
| 168 | } else { | ||
| 169 | py += _rawHeight - (length - _rawWidth); | ||
| 170 | xFactor = 0; | ||
| 171 | yFactor = -_rawHeight; | ||
| 172 | } | ||
| 173 | } | ||
| 174 | var m:Matrix = this.transform.matrix; | ||
| 175 | target.x = px * m.a + py * m.c + m.tx; | ||
| 176 | target.y = px * m.b + py * m.d + m.ty; | ||
| 177 | |||
| 178 | if (autoRotate) { | ||
| 179 | target.rotation = Math.atan2(xFactor * m.b + yFactor * m.d, xFactor * m.a + yFactor * m.c) * _RAD2DEG + rotationOffset; | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | |||
| 184 | //---- GETTERS / SETTERS ---------------------------------------------------------------------- | ||
| 185 | |||
| 186 | /** width of the rectangle in its unrotated, unscaled state (does not factor in any transformations like scaleX/scaleY/rotation) **/ | ||
| 187 | public function get rawWidth():Number { | ||
| 188 | return _rawWidth; | ||
| 189 | } | ||
| 190 | public function set rawWidth(value:Number):void { | ||
| 191 | _rawWidth = value; | ||
| 192 | _redrawLine = true; | ||
| 193 | renderAll(); | ||
| 194 | } | ||
| 195 | |||
| 196 | /** height of the rectangle in its unrotated, unscaled state (does not factor in any transformations like scaleX/scaleY/rotation) **/ | ||
| 197 | public function get rawHeight():Number { | ||
| 198 | return _rawHeight; | ||
| 199 | } | ||
| 200 | public function set rawHeight(value:Number):void { | ||
| 201 | _rawHeight = value; | ||
| 202 | _redrawLine = true; | ||
| 203 | renderAll(); | ||
| 204 | } | ||
| 205 | |||
| 206 | /** height of the rectangle in its unrotated, unscaled state (does not factor in any transformations like scaleX/scaleY/rotation) **/ | ||
| 207 | public function get centerOrigin():Boolean { | ||
| 208 | return _centerOrigin; | ||
| 209 | } | ||
| 210 | public function set centerOrigin(value:Boolean):void { | ||
| 211 | _centerOrigin; | ||
| 212 | _redrawLine = true; | ||
| 213 | renderAll(); | ||
| 214 | } | ||
| 215 | |||
| 216 | } | ||
| 217 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.3 | ||
| 3 | * DATE: 10/17/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.*; | ||
| 11 | /** | ||
| 12 | * Tweening "autoAlpha" is exactly the same as tweening an object's "alpha" except that it ensures | ||
| 13 | * that the object's "visible" property is true until autoAlpha reaches zero at which point it will | ||
| 14 | * toggle the "visible" property to false. That not only improves rendering performance in the Flash Player, | ||
| 15 | * but also hides DisplayObjects so that they don't interact with the mouse. <br /><br /> | ||
| 16 | * | ||
| 17 | * <b>USAGE:</b><br /><br /> | ||
| 18 | * <code> | ||
| 19 | * import com.greensock.TweenLite; <br /> | ||
| 20 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 21 | * import com.greensock.plugins.AutoAlphaPlugin; <br /> | ||
| 22 | * TweenPlugin.activate([AutoAlphaPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 23 | * | ||
| 24 | * TweenLite.to(mc, 2, {autoAlpha:0}); <br /><br /> | ||
| 25 | * </code> | ||
| 26 | * | ||
| 27 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 28 | * | ||
| 29 | * @author Jack Doyle, jack@greensock.com | ||
| 30 | */ | ||
| 31 | public class AutoAlphaPlugin extends TweenPlugin { | ||
| 32 | /** @private **/ | ||
| 33 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 34 | |||
| 35 | /** @private **/ | ||
| 36 | protected var _target:Object; | ||
| 37 | /** @private **/ | ||
| 38 | protected var _ignoreVisible:Boolean; | ||
| 39 | |||
| 40 | /** @private **/ | ||
| 41 | public function AutoAlphaPlugin() { | ||
| 42 | super(); | ||
| 43 | this.propName = "autoAlpha"; | ||
| 44 | this.overwriteProps = ["alpha","visible"]; | ||
| 45 | } | ||
| 46 | |||
| 47 | /** @private **/ | ||
| 48 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 49 | _target = target; | ||
| 50 | addTween(target, "alpha", target.alpha, value, "alpha"); | ||
| 51 | return true; | ||
| 52 | } | ||
| 53 | |||
| 54 | /** @private **/ | ||
| 55 | override public function killProps(lookup:Object):void { | ||
| 56 | super.killProps(lookup); | ||
| 57 | _ignoreVisible = Boolean("visible" in lookup); | ||
| 58 | } | ||
| 59 | |||
| 60 | /** @private **/ | ||
| 61 | override public function set changeFactor(n:Number):void { | ||
| 62 | updateTweens(n); | ||
| 63 | if (!_ignoreVisible) { | ||
| 64 | _target.visible = Boolean(_target.alpha != 0); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | } | ||
| 69 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.0 | ||
| 3 | * DATE: 8/18/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.filters.*; | ||
| 9 | import flash.display.*; | ||
| 10 | import com.greensock.*; | ||
| 11 | /** | ||
| 12 | * Tweens a BevelFilter. The following properties are available (you only need to define the ones you want to tween): <br /> | ||
| 13 | * <code> | ||
| 14 | * <ul> | ||
| 15 | * <li> distance : Number [0]</li> | ||
| 16 | * <li> angle : Number [0]</li> | ||
| 17 | * <li> highlightColor : uint [0xFFFFFF]</li> | ||
| 18 | * <li> highlightAlpha : Number [0.5]</li> | ||
| 19 | * <li> shadowColor : uint [0x000000]</li> | ||
| 20 | * <li> shadowAlpha :Number [0.5]</li> | ||
| 21 | * <li> blurX : Number [2]</li> | ||
| 22 | * <li> blurY : Number [2]</li> | ||
| 23 | * <li> strength : Number [0]</li> | ||
| 24 | * <li> quality : uint [2]</li> | ||
| 25 | * <li> index : uint</li> | ||
| 26 | * <li> addFilter : Boolean [false]</li> | ||
| 27 | * <li> remove : Boolean [false]</li> | ||
| 28 | * </ul> | ||
| 29 | * </code> | ||
| 30 | * | ||
| 31 | * | ||
| 32 | * <b>USAGE:</b><br /><br /> | ||
| 33 | * <code> | ||
| 34 | * import com.greensock.TweenLite; <br /> | ||
| 35 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 36 | * import com.greensock.plugins.BevelFilterPlugin; <br /> | ||
| 37 | * TweenPlugin.activate([BevelFilterPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 38 | * | ||
| 39 | * TweenLite.to(mc, 1, {bevelFilter:{blurX:10, blurY:10, distance:6, angle:45, strength:1}});<br /><br /> | ||
| 40 | * </code> | ||
| 41 | * | ||
| 42 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 43 | * | ||
| 44 | * @author Jack Doyle, jack@greensock.com | ||
| 45 | */ | ||
| 46 | public class BevelFilterPlugin extends FilterPlugin { | ||
| 47 | /** @private **/ | ||
| 48 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 49 | /** @private **/ | ||
| 50 | private static var _propNames:Array = ["distance","angle","highlightColor","highlightAlpha","shadowColor","shadowAlpha","blurX","blurY","strength","quality"]; | ||
| 51 | |||
| 52 | /** @private **/ | ||
| 53 | public function BevelFilterPlugin() { | ||
| 54 | super(); | ||
| 55 | this.propName = "bevelFilter"; | ||
| 56 | this.overwriteProps = ["bevelFilter"]; | ||
| 57 | } | ||
| 58 | |||
| 59 | /** @private **/ | ||
| 60 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 61 | _target = target; | ||
| 62 | _type = BevelFilter; | ||
| 63 | initFilter(value, new BevelFilter(0, 0, 0xFFFFFF, 0.5, 0x000000, 0.5, 2, 2, 0, value.quality || 2), _propNames); | ||
| 64 | return true; | ||
| 65 | } | ||
| 66 | |||
| 67 | } | ||
| 68 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.21 | ||
| 3 | * DATE: 2010-06-23 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | /** | ||
| 10 | * Bezier tweening allows you to tween in a non-linear way. For example, you may want to tween | ||
| 11 | * a MovieClip's position from the origin (0,0) 500 pixels to the right (500,0) but curve downwards | ||
| 12 | * through the middle of the tween. Simply pass as many objects in the bezier Array as you'd like, | ||
| 13 | * one for each "control point" (see documentation on Flash's curveTo() drawing method for more | ||
| 14 | * about how control points work).<br /><br /> | ||
| 15 | * | ||
| 16 | * Keep in mind that you can bezier tween ANY properties, not just x/y. <br /><br /> | ||
| 17 | * | ||
| 18 | * Also, if you'd like to rotate the target in the direction of the bezier path, | ||
| 19 | * use the <code>orientToBezier</code> special property. In order to alter a rotation property accurately, | ||
| 20 | * TweenLite/Max needs 5 pieces of information: <br /> | ||
| 21 | * <ol> | ||
| 22 | * <li> Position property 1 (typically <code>"x"</code>)</li> | ||
| 23 | * <li> Position property 2 (typically <code>"y"</code>)</li> | ||
| 24 | * <li> Rotational property (typically <code>"rotation"</code>)</li> | ||
| 25 | * <li> Number of degrees to add (optional - makes it easy to orient your MovieClip properly)</li> | ||
| 26 | * <li> Tolerance (default is 0.01, but increase this if the rotation seems to jitter during the tween)</li> | ||
| 27 | * </ol><br /> | ||
| 28 | * | ||
| 29 | * The <code>orientToBezier</code> property should be an Array containing one Array for each set of these values. | ||
| 30 | * For maximum flexibility, you can pass in any number of arrays inside the container array, one | ||
| 31 | * for each rotational property. This can be convenient when working in 3D because you can rotate | ||
| 32 | * on multiple axis. If you're doing a standard 2D x/y tween on a bezier, you can simply pass | ||
| 33 | * in a Boolean value of true and TweenLite/Max will use a typical setup, <code>[["x", "y", "rotation", 0, 0.01]]</code>. | ||
| 34 | * Hint: Don't forget the container Array (notice the double outer brackets)<br /><br /> | ||
| 35 | * | ||
| 36 | * <b>USAGE:</b><br /><br /> | ||
| 37 | * <code> | ||
| 38 | * import com.greensock.TweenLite; <br /> | ||
| 39 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 40 | * import com.greensock.plugins.BezierPlugin; <br /> | ||
| 41 | * TweenPlugin.activate([BezierPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 42 | * | ||
| 43 | * TweenLite.to(mc, 3, {bezier:[{x:250, y:50}, {x:500, y:0}]}); //makes my_mc travel through 250,50 and end up at 500,0. <br /><br /> | ||
| 44 | * </code> | ||
| 45 | * | ||
| 46 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 47 | * | ||
| 48 | * @author Jack Doyle, jack@greensock.com | ||
| 49 | */ | ||
| 50 | public class BezierPlugin extends TweenPlugin { | ||
| 51 | /** @private **/ | ||
| 52 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 53 | |||
| 54 | /** @private **/ | ||
| 55 | protected static const _RAD2DEG:Number = 180 / Math.PI; //precalculate for speed | ||
| 56 | |||
| 57 | /** @private **/ | ||
| 58 | protected var _target:Object; | ||
| 59 | /** @private **/ | ||
| 60 | protected var _orientData:Array; | ||
| 61 | /** @private **/ | ||
| 62 | protected var _orient:Boolean; | ||
| 63 | /** @private used for orientToBezier projections **/ | ||
| 64 | protected var _future:Object = {}; | ||
| 65 | /** @private **/ | ||
| 66 | protected var _beziers:Object; | ||
| 67 | |||
| 68 | /** @private **/ | ||
| 69 | public function BezierPlugin() { | ||
| 70 | super(); | ||
| 71 | this.propName = "bezier"; //name of the special property that the plugin should intercept/manage | ||
| 72 | this.overwriteProps = []; //will be populated in init() | ||
| 73 | } | ||
| 74 | |||
| 75 | /** @private **/ | ||
| 76 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 77 | if (!(value is Array)) { | ||
| 78 | return false; | ||
| 79 | } | ||
| 80 | init(tween, value as Array, false); | ||
| 81 | return true; | ||
| 82 | } | ||
| 83 | |||
| 84 | /** @private **/ | ||
| 85 | protected function init(tween:TweenLite, beziers:Array, through:Boolean):void { | ||
| 86 | _target = tween.target; | ||
| 87 | var enumerables:Object = (tween.vars.isTV == true) ? tween.vars.exposedVars : tween.vars; //for TweenLiteVars and TweenMaxVars (we need an object with enumerable properties); | ||
| 88 | if (enumerables.orientToBezier == true) { | ||
| 89 | _orientData = [["x", "y", "rotation", 0, 0.01]]; | ||
| 90 | _orient = true; | ||
| 91 | } else if (enumerables.orientToBezier is Array) { | ||
| 92 | _orientData = enumerables.orientToBezier; | ||
| 93 | _orient = true; | ||
| 94 | } | ||
| 95 | var props:Object = {}, i:int, p:String, killVarsLookup:Object; | ||
| 96 | for (i = 0; i < beziers.length; i++) { | ||
| 97 | for (p in beziers[i]) { | ||
| 98 | if (props[p] == undefined) { | ||
| 99 | props[p] = [tween.target[p]]; | ||
| 100 | } | ||
| 101 | if (typeof(beziers[i][p]) == "number") { | ||
| 102 | props[p].push(beziers[i][p]); | ||
| 103 | } else { | ||
| 104 | props[p].push(tween.target[p] + Number(beziers[i][p])); //relative value | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | for (p in props) { | ||
| 109 | this.overwriteProps[this.overwriteProps.length] = p; | ||
| 110 | if (enumerables[p] != undefined) { | ||
| 111 | if (typeof(enumerables[p]) == "number") { | ||
| 112 | props[p].push(enumerables[p]); | ||
| 113 | } else { | ||
| 114 | props[p].push(tween.target[p] + Number(enumerables[p])); //relative value | ||
| 115 | } | ||
| 116 | killVarsLookup = {}; | ||
| 117 | killVarsLookup[p] = true; | ||
| 118 | tween.killVars(killVarsLookup, false); | ||
| 119 | delete enumerables[p]; //in case TweenLite/Max hasn't reached the enumerable yet in its init() function. This prevents normal tweens from getting created for the properties that should be controled with the BezierPlugin. | ||
| 120 | } | ||
| 121 | } | ||
| 122 | _beziers = parseBeziers(props, through); | ||
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 126 | * Helper method for translating control points into bezier information. | ||
| 127 | * | ||
| 128 | * @param props Object containing a property corresponding to each one you'd like bezier paths for. Each property's value should be a single Array with the numeric point values (i.e. <code>props.x = [12,50,80]</code> and <code>props.y = [50,97,158]</code>). | ||
| 129 | * @param through If you want the paths drawn THROUGH the supplied control points, set this to true. | ||
| 130 | * @return A new object with an Array of values for each property. The first element in the Array is the start value, the second is the control point, and the 3rd is the end value. (i.e. <code>returnObject.x = [[12, 32, 50}, [50, 65, 80]]</code>) | ||
| 131 | */ | ||
| 132 | public static function parseBeziers(props:Object, through:Boolean=false):Object { | ||
| 133 | var i:int, a:Array, b:Object, p:String; | ||
| 134 | var all:Object = {}; | ||
| 135 | if (through) { | ||
| 136 | for (p in props) { | ||
| 137 | a = props[p]; | ||
| 138 | all[p] = b = []; | ||
| 139 | if (a.length > 2) { | ||
| 140 | b[b.length] = [a[0], a[1] - ((a[2] - a[0]) / 4), a[1]]; | ||
| 141 | for (i = 1; i < a.length - 1; i++) { | ||
| 142 | b[b.length] = [a[i], a[i] + (a[i] - b[i - 1][1]), a[i + 1]]; | ||
| 143 | } | ||
| 144 | } else { | ||
| 145 | b[b.length] = [a[0], (a[0] + a[1]) / 2, a[1]]; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | } else { | ||
| 149 | for (p in props) { | ||
| 150 | a = props[p]; | ||
| 151 | all[p] = b = []; | ||
| 152 | if (a.length > 3) { | ||
| 153 | b[b.length] = [a[0], a[1], (a[1] + a[2]) / 2]; | ||
| 154 | for (i = 2; i < a.length - 2; i++) { | ||
| 155 | b[b.length] = [b[i - 2][2], a[i], (a[i] + a[i + 1]) / 2]; | ||
| 156 | } | ||
| 157 | b[b.length] = [b[b.length - 1][2], a[a.length - 2], a[a.length - 1]]; | ||
| 158 | } else if (a.length == 3) { | ||
| 159 | b[b.length] = [a[0], a[1], a[2]]; | ||
| 160 | } else if (a.length == 2) { | ||
| 161 | b[b.length] = [a[0], (a[0] + a[1]) / 2, a[1]]; | ||
| 162 | } | ||
| 163 | } | ||
| 164 | } | ||
| 165 | return all; | ||
| 166 | } | ||
| 167 | |||
| 168 | /** @private **/ | ||
| 169 | override public function killProps(lookup:Object):void { | ||
| 170 | for (var p:String in _beziers) { | ||
| 171 | if (p in lookup) { | ||
| 172 | delete _beziers[p]; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | super.killProps(lookup); | ||
| 176 | } | ||
| 177 | |||
| 178 | /** @private **/ | ||
| 179 | override public function set changeFactor(n:Number):void { | ||
| 180 | var i:int, p:String, b:Object, t:Number, segments:uint, val:Number; | ||
| 181 | _changeFactor = n; | ||
| 182 | if (n == 1) { //to make sure the end values are EXACTLY what they need to be. | ||
| 183 | for (p in _beziers) { | ||
| 184 | i = _beziers[p].length - 1; | ||
| 185 | _target[p] = _beziers[p][i][2]; | ||
| 186 | } | ||
| 187 | } else { | ||
| 188 | for (p in _beziers) { | ||
| 189 | segments = _beziers[p].length; | ||
| 190 | if (n < 0) { | ||
| 191 | i = 0; | ||
| 192 | } else if (n >= 1) { | ||
| 193 | i = segments - 1; | ||
| 194 | } else { | ||
| 195 | i = int(segments * n); | ||
| 196 | } | ||
| 197 | t = (n - (i * (1 / segments))) * segments; | ||
| 198 | b = _beziers[p][i]; | ||
| 199 | if (this.round) { | ||
| 200 | val = b[0] + t * (2 * (1 - t) * (b[1] - b[0]) + t * (b[2] - b[0])); | ||
| 201 | _target[p] = (val > 0) ? int(val + 0.5) : int(val - 0.5); //4 times as fast as Math.round() | ||
| 202 | } else { | ||
| 203 | _target[p] = b[0] + t * (2 * (1 - t) * (b[1] - b[0]) + t * (b[2] - b[0])); | ||
| 204 | } | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | if (_orient) { | ||
| 209 | i = _orientData.length; | ||
| 210 | var curVals:Object = {}, dx:Number, dy:Number, cotb:Array, toAdd:Number; | ||
| 211 | while (i--) { | ||
| 212 | cotb = _orientData[i]; //current orientToBezier Array | ||
| 213 | curVals[cotb[0]] = _target[cotb[0]]; | ||
| 214 | curVals[cotb[1]] = _target[cotb[1]]; | ||
| 215 | } | ||
| 216 | |||
| 217 | var oldTarget:Object = _target, oldRound:Boolean = this.round; | ||
| 218 | _target = _future; | ||
| 219 | this.round = false; | ||
| 220 | _orient = false; | ||
| 221 | i = _orientData.length; | ||
| 222 | while (i--) { | ||
| 223 | cotb = _orientData[i]; //current orientToBezier Array | ||
| 224 | this.changeFactor = n + (cotb[4] || 0.01); | ||
| 225 | toAdd = cotb[3] || 0; | ||
| 226 | dx = _future[cotb[0]] - curVals[cotb[0]]; | ||
| 227 | dy = _future[cotb[1]] - curVals[cotb[1]]; | ||
| 228 | oldTarget[cotb[2]] = Math.atan2(dy, dx) * _RAD2DEG + toAdd; | ||
| 229 | } | ||
| 230 | _target = oldTarget; | ||
| 231 | this.round = oldRound; | ||
| 232 | _orient = true; | ||
| 233 | } | ||
| 234 | |||
| 235 | } | ||
| 236 | |||
| 237 | } | ||
| 238 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.12 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | /** | ||
| 10 | * Identical to bezier except that instead of defining bezier control point values, you | ||
| 11 | * define points through which the bezier values should move. This can be more intuitive | ||
| 12 | * than using control points. Simply pass as many objects in the bezier Array as you'd like, | ||
| 13 | * one for each point through which the values should travel. For example, if you want the | ||
| 14 | * curved motion path to travel through the coordinates x:250, y:100 and x:50, y:200 and then | ||
| 15 | * end up at 500, 100, you'd do: <br /><br /> | ||
| 16 | * | ||
| 17 | * <code>TweenLite.to(mc, 2, {bezierThrough:[{x:250, y:100}, {x:50, y:200}, {x:500, y:200}]});</code><br /><br /> | ||
| 18 | * | ||
| 19 | * Keep in mind that you can bezierThrough tween ANY properties, not just x/y. <br /><br /> | ||
| 20 | * | ||
| 21 | * Also, if you'd like to rotate the target in the direction of the bezier path, | ||
| 22 | * use the orientToBezier special property. In order to alter a rotation property accurately, | ||
| 23 | * TweenLite/Max needs 5 pieces of information: | ||
| 24 | * <ol> | ||
| 25 | * <li> Position property 1 (typically <code>"x"</code>)</li> | ||
| 26 | * <li> Position property 2 (typically <code>"y"</code>)</li> | ||
| 27 | * <li> Rotational property (typically <code>"rotation"</code>)</li> | ||
| 28 | * <li> Number of degrees to add (optional - makes it easy to orient your MovieClip properly)</li> | ||
| 29 | * <li> Tolerance (default is 0.01, but increase this if the rotation seems to jitter during the tween)</li> | ||
| 30 | * </ol><br /> | ||
| 31 | * | ||
| 32 | * The orientToBezier property should be an Array containing one Array for each set of these values. | ||
| 33 | * For maximum flexibility, you can pass in any number of arrays inside the container array, one | ||
| 34 | * for each rotational property. This can be convenient when working in 3D because you can rotate | ||
| 35 | * on multiple axis. If you're doing a standard 2D x/y tween on a bezier, you can simply pass | ||
| 36 | * in a boolean value of true and TweenLite/Max will use a typical setup, <code>[["x", "y", "rotation", 0, 0.01]]</code>. | ||
| 37 | * Hint: Don't forget the container Array (notice the double outer brackets) <br /><br /> | ||
| 38 | * | ||
| 39 | * <b>USAGE:</b><br /><br /> | ||
| 40 | * <code> | ||
| 41 | * import com.greensock.TweenLite; <br /> | ||
| 42 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 43 | * import com.greensock.plugins.BezierThroughPlugin; <br /> | ||
| 44 | * TweenPlugin.activate([BezierThroughPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 45 | * | ||
| 46 | * TweenLite.to(mc, 2, {bezierThrough:[{x:250, y:100}, {x:50, y:200}, {x:500, y:200}]}); <br /><br /> | ||
| 47 | * </code> | ||
| 48 | * | ||
| 49 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 50 | * | ||
| 51 | * @author Jack Doyle, jack@greensock.com | ||
| 52 | */ | ||
| 53 | public class BezierThroughPlugin extends BezierPlugin { | ||
| 54 | /** @private **/ | ||
| 55 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 56 | |||
| 57 | /** @private **/ | ||
| 58 | public function BezierThroughPlugin() { | ||
| 59 | super(); | ||
| 60 | this.propName = "bezierThrough"; //name of the special property that the plugin should intercept/manage | ||
| 61 | } | ||
| 62 | |||
| 63 | /** @private **/ | ||
| 64 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 65 | if (!(value is Array)) { | ||
| 66 | return false; | ||
| 67 | } | ||
| 68 | init(tween, value as Array, true); | ||
| 69 | return true; | ||
| 70 | } | ||
| 71 | |||
| 72 | } | ||
| 73 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.0 | ||
| 3 | * DATE: 8/18/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.filters.*; | ||
| 9 | import flash.display.*; | ||
| 10 | import com.greensock.*; | ||
| 11 | /** | ||
| 12 | * Tweens a BlurFilter. The following properties are available (you only need to define the ones you want to tween): | ||
| 13 | * <code> | ||
| 14 | * <ul> | ||
| 15 | * <li> blurX : Number [0]</li> | ||
| 16 | * <li> blurY : Number [0]</li> | ||
| 17 | * <li> quality : uint [2]</li> | ||
| 18 | * <li> index : uint</li> | ||
| 19 | * <li> addFilter : Boolean [false]</li> | ||
| 20 | * <li> remove : Boolean [false]</li> | ||
| 21 | * </ul> | ||
| 22 | * </code> | ||
| 23 | * | ||
| 24 | * Set <code>remove</code> to true if you want the filter to be removed when the tween completes. <br /><br /> | ||
| 25 | * | ||
| 26 | * <b>USAGE:</b><br /><br /> | ||
| 27 | * <code> | ||
| 28 | * import com.greensock.TweenLite; <br /> | ||
| 29 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 30 | * import com.greensock.plugins.BlurFilterPlugin; <br /> | ||
| 31 | * TweenPlugin.activate([BlurFilterPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 32 | * | ||
| 33 | * TweenLite.to(mc, 1, {blurFilter:{blurX:10, blurY:10}}); <br /><br /> | ||
| 34 | * </code> | ||
| 35 | * | ||
| 36 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 37 | * | ||
| 38 | * @author Jack Doyle, jack@greensock.com | ||
| 39 | */ | ||
| 40 | public class BlurFilterPlugin extends FilterPlugin { | ||
| 41 | /** @private **/ | ||
| 42 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 43 | /** @private **/ | ||
| 44 | private static var _propNames:Array = ["blurX","blurY","quality"]; | ||
| 45 | |||
| 46 | /** @private **/ | ||
| 47 | public function BlurFilterPlugin() { | ||
| 48 | super(); | ||
| 49 | this.propName = "blurFilter"; | ||
| 50 | this.overwriteProps = ["blurFilter"]; | ||
| 51 | } | ||
| 52 | |||
| 53 | /** @private **/ | ||
| 54 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 55 | _target = target; | ||
| 56 | _type = BlurFilter; | ||
| 57 | initFilter(value, new BlurFilter(0, 0, value.quality || 2), _propNames); | ||
| 58 | return true; | ||
| 59 | } | ||
| 60 | |||
| 61 | } | ||
| 62 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 2010-06-29 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.DisplayObject; | ||
| 11 | /** | ||
| 12 | * Forces the <code>cacheAsBitmap</code> property of a DisplayObject to be a certain value (<code>true</code> or <code>false</code>) | ||
| 13 | * during the tween and then sets it back to whatever it was before the tween was rendered for the first time. This <i>can</i> improve | ||
| 14 | * performance in certain situations, like when the DisplayObject <strong>NOT</strong> tweening its rotation, scaleX, scaleY, or similar | ||
| 15 | * things with its <code>transform.matrix</code>. See Adobe's docs for details about when it is appropriate to set <code>cacheAsBitmap</code> | ||
| 16 | * to <code>true</code>. Also beware that whenever a DisplayObject's <code>cacheAsBitmap</code> is <code>true</code>, it will ONLY be | ||
| 17 | * rendered on whole pixel values which can lead to animation that looks "choppy" at slow speeds.<br /><br /> | ||
| 18 | * | ||
| 19 | * For example, if you want to set <code>cacheAsBitmap</code> to <code>true</code> while the tween is running, do:<br /><br /><code> | ||
| 20 | * | ||
| 21 | * TweenLite.to(mc, 1, {x:100, cacheAsBitmap:true});<br /><br /></code> | ||
| 22 | * | ||
| 23 | * <b>USAGE:</b><br /><br /> | ||
| 24 | * <code> | ||
| 25 | * import com.greensock.TweenLite; <br /> | ||
| 26 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 27 | * import com.greensock.plugins.CacheAsBitmapPlugin; <br /> | ||
| 28 | * TweenPlugin.activate([CacheAsBitmapPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 29 | * | ||
| 30 | * TweenLite.to(mc, 1, {x:100, cacheAsBitmap:true}); <br /><br /> | ||
| 31 | * </code> | ||
| 32 | * | ||
| 33 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 34 | * | ||
| 35 | * @author Jack Doyle, jack@greensock.com | ||
| 36 | */ | ||
| 37 | public class CacheAsBitmapPlugin extends TweenPlugin { | ||
| 38 | /** @private **/ | ||
| 39 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 40 | |||
| 41 | /** @private **/ | ||
| 42 | protected var _target:DisplayObject; | ||
| 43 | /** @private **/ | ||
| 44 | protected var _tween:TweenLite; | ||
| 45 | /** @private **/ | ||
| 46 | protected var _cacheAsBitmap:Boolean; | ||
| 47 | /** @private **/ | ||
| 48 | protected var _initVal:Boolean; | ||
| 49 | |||
| 50 | /** @private **/ | ||
| 51 | public function CacheAsBitmapPlugin() { | ||
| 52 | super(); | ||
| 53 | this.propName = "cacheAsBitmap"; | ||
| 54 | this.overwriteProps = ["cacheAsBitmap"]; | ||
| 55 | } | ||
| 56 | |||
| 57 | /** @private **/ | ||
| 58 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 59 | _target = target as DisplayObject; | ||
| 60 | _tween = tween; | ||
| 61 | _initVal = _target.cacheAsBitmap; | ||
| 62 | _cacheAsBitmap = Boolean(value); | ||
| 63 | return true; | ||
| 64 | } | ||
| 65 | |||
| 66 | /** @private **/ | ||
| 67 | override public function set changeFactor(n:Number):void { | ||
| 68 | if (_tween.cachedDuration == _tween.cachedTime || _tween.cachedTime == 0) { //a changeFactor of 1 doesn't necessarily mean the tween is done - if the ease is Elastic.easeOut or Back.easeOut for example, they could hit 1 mid-tween. | ||
| 69 | _target.cacheAsBitmap = _initVal; | ||
| 70 | } else if (_target.cacheAsBitmap != _cacheAsBitmap) { | ||
| 71 | _target.cacheAsBitmap = _cacheAsBitmap; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | } | ||
| 76 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.2 (beta) | ||
| 3 | * DATE: 2010-04-16 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | import com.greensock.motionPaths.CirclePath2D; | ||
| 10 | import com.greensock.motionPaths.PathFollower; | ||
| 11 | |||
| 12 | import flash.display.*; | ||
| 13 | import flash.geom.Matrix; | ||
| 14 | /** | ||
| 15 | * Tweens an object along a CirclePath2D motion path in any direction (clockwise, counter-clockwise, or shortest). | ||
| 16 | * The plugin recognizes the following properties: | ||
| 17 | * <ul> | ||
| 18 | * <li><b>path</b> : CirclePath2D - The CirclePath2D instance to follow (com.greensock.motionPaths.CirclePath2D)</li> | ||
| 19 | * <li><b>startAngle</b> : Number - The position at which the target should begin its rotation (described | ||
| 20 | * in degrees unless useRadians is true in which case it is described in radians). | ||
| 21 | * For example, to begin at the top of the circle, use 270 or -90 as the startAngle.</li> | ||
| 22 | * <li><b>endAngle</b> : Number - The position at which the target should end its rotation (described in | ||
| 23 | * degrees unless useRadians is true in which case it is described in radians). | ||
| 24 | * For example, to end at the bottom of the circle, use 90 as the endAngle</li> | ||
| 25 | * <li><b>autoRotate</b> : Boolean - When <code>autoRotate</code> is <code>true</code>, the target will automatically | ||
| 26 | * be rotated so that it is oriented to the angle of the path. To offset this value (like to always add | ||
| 27 | * 90 degrees for example), use the <code>rotationOffset</code> property.</li> | ||
| 28 | * <li><b>rotationOffset</b> : Number - When <code>autoRotate</code> is <code>true</code>, this value will always | ||
| 29 | * be added to the resulting <code>rotation</code> of the target.</li> | ||
| 30 | * <li><b>direction</b> : String - The direction in which the target should travel around the path. Options are | ||
| 31 | * <code>Direction.CLOCKWISE</code> ("clockwise"), <code>Direction.COUNTER_CLOCKWISE</code> | ||
| 32 | * ("counterClockwise"), or <code>Direction.SHORTEST</code> ("shortest").</li> | ||
| 33 | * <li><b>extraRevolutions</b> : uint - If instead of going directly to the endAngle, you want the target to | ||
| 34 | * travel one or more extra revolutions around the path before going to the endAngle, | ||
| 35 | * define that number of revolutions here. </li> | ||
| 36 | * <li><b>useRadians</b> : Boolean - If you prefer to define values in radians instead of degrees, set useRadians to true.</li> | ||
| 37 | * </ul> | ||
| 38 | * | ||
| 39 | * <br /><br /> | ||
| 40 | * | ||
| 41 | * <b>USAGE:</b><br /><br /> | ||
| 42 | * <code> | ||
| 43 | * import com.greensock.~~; <br /> | ||
| 44 | * import com.greensock.plugins.~~; <br /> | ||
| 45 | * import com.greensock.motionPaths.~~<br /> | ||
| 46 | * TweenPlugin.activate([CirclePath2DPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 47 | * | ||
| 48 | * var circle:CirclePath2D = new CirclePath2D(150, 150, 100); | ||
| 49 | * TweenLite.to(mc, 2, {circlePath2D:{path:circle, startAngle:90, endAngle:270, direction:Direction.CLOCKWISE, extraRevolutions:2}}); <br /><br /> | ||
| 50 | * </code> | ||
| 51 | * | ||
| 52 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 53 | * | ||
| 54 | * @author Jack Doyle, jack@greensock.com | ||
| 55 | */ | ||
| 56 | public class CirclePath2DPlugin extends TweenPlugin { | ||
| 57 | /** @private **/ | ||
| 58 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 59 | /** @private **/ | ||
| 60 | private static const _2PI:Number = Math.PI * 2; | ||
| 61 | /** @private **/ | ||
| 62 | private static const _RAD2DEG:Number = 180 / Math.PI; | ||
| 63 | |||
| 64 | /** @private **/ | ||
| 65 | protected var _target:Object; | ||
| 66 | /** @private **/ | ||
| 67 | protected var _autoRemove:Boolean; | ||
| 68 | /** @private **/ | ||
| 69 | protected var _start:Number; | ||
| 70 | /** @private **/ | ||
| 71 | protected var _change:Number; | ||
| 72 | /** @private **/ | ||
| 73 | protected var _circle:CirclePath2D; | ||
| 74 | /** @private **/ | ||
| 75 | protected var _autoRotate:Boolean; | ||
| 76 | /** @private **/ | ||
| 77 | protected var _rotationOffset:Number; | ||
| 78 | |||
| 79 | /** @private **/ | ||
| 80 | public function CirclePath2DPlugin() { | ||
| 81 | super(); | ||
| 82 | this.propName = "circlePath2D"; | ||
| 83 | this.overwriteProps = ["x","y"]; | ||
| 84 | } | ||
| 85 | |||
| 86 | /** @private **/ | ||
| 87 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 88 | if (!("path" in value) || !(value.path is CirclePath2D)) { | ||
| 89 | trace("CirclePath2DPlugin error: invalid 'path' property. Please define a CirclePath2D instance."); | ||
| 90 | return false; | ||
| 91 | } | ||
| 92 | _target = target; | ||
| 93 | _circle = value.path as CirclePath2D; | ||
| 94 | _autoRotate = Boolean(value.autoRotate == true); | ||
| 95 | _rotationOffset = value.rotationOffset || 0; | ||
| 96 | |||
| 97 | var f:PathFollower = _circle.getFollower(target); | ||
| 98 | if (f != null && !("startAngle" in value)) { | ||
| 99 | _start = f.progress; | ||
| 100 | } else { | ||
| 101 | _start = _circle.angleToProgress(value.startAngle || 0, value.useRadians); | ||
| 102 | _circle.renderObjectAt(_target, _start); | ||
| 103 | } | ||
| 104 | _change = Number(_circle.anglesToProgressChange(_circle.progressToAngle(_start), value.endAngle || 0, value.direction || "clockwise", value.extraRevolutions || 0, Boolean(value.useRadians))); | ||
| 105 | return true; | ||
| 106 | } | ||
| 107 | |||
| 108 | /** @private **/ | ||
| 109 | override public function killProps(lookup:Object):void { | ||
| 110 | super.killProps(lookup); | ||
| 111 | if (("x" in lookup) || ("y" in lookup)) { | ||
| 112 | this.overwriteProps = []; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | /** @private **/ | ||
| 117 | override public function set changeFactor(n:Number):void { | ||
| 118 | var angle:Number = (_start + (_change * n)) * _2PI; | ||
| 119 | var radius:Number = _circle.radius; | ||
| 120 | var m:Matrix = _circle.transform.matrix; | ||
| 121 | var px:Number = Math.cos(angle) * radius; | ||
| 122 | var py:Number = Math.sin(angle) * radius; | ||
| 123 | _target.x = px * m.a + py * m.c + m.tx; | ||
| 124 | _target.y = px * m.b + py * m.d + m.ty; | ||
| 125 | |||
| 126 | if (_autoRotate) { | ||
| 127 | angle += Math.PI / 2; | ||
| 128 | px = Math.cos(angle) * _circle.radius; | ||
| 129 | py = Math.sin(angle) * _circle.radius; | ||
| 130 | _target.rotation = Math.atan2(px * m.b + py * m.d, px * m.a + py * m.c) * _RAD2DEG + _rotationOffset; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | } | ||
| 135 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.0 | ||
| 3 | * DATE: 8/18/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import flash.filters.*; | ||
| 10 | import com.greensock.*; | ||
| 11 | /** | ||
| 12 | * ColorMatrixFilter tweening offers an easy way to tween a DisplayObject's saturation, hue, contrast, | ||
| 13 | * brightness, and colorization. The following properties are available (you only need to define the ones you want to tween): | ||
| 14 | * <ul> | ||
| 15 | * <li><code> colorize : uint </code> (colorizing a DisplayObject makes it look as though you're seeing it through a colored piece of glass whereas tinting it makes every pixel exactly that color. You can control the amount of colorization using the "amount" value where 1 is full strength, 0.5 is half-strength, and 0 has no colorization effect.)</li> | ||
| 16 | * <li><code> amount : Number [1] </code> (only used in conjunction with "colorize")</li> | ||
| 17 | * <li><code> contrast : Number </code> (1 is normal contrast, 0 has no contrast, and 2 is double the normal contrast, etc.)</li> | ||
| 18 | * <li><code> saturation : Number </code> (1 is normal saturation, 0 makes the DisplayObject look black and white, and 2 would be double the normal saturation)</li> | ||
| 19 | * <li><code> hue : Number </code> (changes the hue of every pixel. Think of it as degrees, so 180 would be rotating the hue to be exactly opposite as normal, 360 would be the same as 0, etc.)</li> | ||
| 20 | * <li><code> brightness : Number </code> (1 is normal brightness, 0 is much darker than normal, and 2 is twice the normal brightness, etc.)</li> | ||
| 21 | * <li><code> threshold : Number </code> (number from 0 to 255 that controls the threshold of where the pixels turn white or black)</li> | ||
| 22 | * <li><code> matrix : Array </code> (If you already have a matrix from a ColorMatrixFilter that you want to tween to, pass it in with the "matrix" property. This makes it possible to match effects created in the Flash IDE.)</li> | ||
| 23 | * <li><code> index : Number </code> (only necessary if you already have a filter applied and you want to target it with the tween.)</li> | ||
| 24 | * <li><code> addFilter : Boolean [false] </code></li> | ||
| 25 | * <li><code> remove : Boolean [false] </code> (Set remove to true if you want the filter to be removed when the tween completes.)</li> | ||
| 26 | * </ul> | ||
| 27 | * HINT: If you'd like to match the ColorMatrixFilter values you created in the Flash IDE on a particular object, you can get its matrix like this:<br /><br /><code> | ||
| 28 | * | ||
| 29 | * import flash.display.DisplayObject; <br /> | ||
| 30 | * import flash.filters.ColorMatrixFilter; <br /><br /> | ||
| 31 | * | ||
| 32 | * function getColorMatrix(mc:DisplayObject):Array { <br /> | ||
| 33 | * var f:Array = mc.filters, i:uint; <br /> | ||
| 34 | * for (i = 0; i < f.length; i++) { <br /> | ||
| 35 | * if (f[i] is ColorMatrixFilter) { <br /> | ||
| 36 | * return f[i].matrix; <br /> | ||
| 37 | * } <br /> | ||
| 38 | * } <br /> | ||
| 39 | * return null; <br /> | ||
| 40 | * } <br /><br /> | ||
| 41 | * | ||
| 42 | * var myOriginalMatrix:Array = getColorMatrix(my_mc); //store it so you can tween back to it anytime like TweenMax.to(my_mc, 1, {colorMatrixFilter:{matrix:myOriginalMatrix}}); | ||
| 43 | * </code> | ||
| 44 | * <br /><br /> | ||
| 45 | * | ||
| 46 | * <b>USAGE:</b><br /><br /> | ||
| 47 | * <code> | ||
| 48 | * import com.greensock.TweenLite; <br /> | ||
| 49 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 50 | * import com.greensock.plugins.ColorMatrixFilterPlugin; <br /> | ||
| 51 | * TweenPlugin.activate([ColorMatrixFilterPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 52 | * | ||
| 53 | * TweenLite.to(mc, 1, {colorMatrixFilter:{colorize:0xFF0000}}); <br /><br /> | ||
| 54 | * </code> | ||
| 55 | * | ||
| 56 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 57 | * | ||
| 58 | * @author Jack Doyle, jack@greensock.com | ||
| 59 | */ | ||
| 60 | public class ColorMatrixFilterPlugin extends FilterPlugin { | ||
| 61 | /** @private **/ | ||
| 62 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 63 | /** @private **/ | ||
| 64 | private static var _propNames:Array = []; | ||
| 65 | |||
| 66 | /** @private **/ | ||
| 67 | protected static var _idMatrix:Array = [1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0]; | ||
| 68 | /** @private **/ | ||
| 69 | protected static var _lumR:Number = 0.212671; //Red constant - used for a few color matrix filter functions | ||
| 70 | /** @private **/ | ||
| 71 | protected static var _lumG:Number = 0.715160; //Green constant - used for a few color matrix filter functions | ||
| 72 | /** @private **/ | ||
| 73 | protected static var _lumB:Number = 0.072169; //Blue constant - used for a few color matrix filter functions | ||
| 74 | |||
| 75 | /** @private **/ | ||
| 76 | protected var _matrix:Array; | ||
| 77 | /** @private **/ | ||
| 78 | protected var _matrixTween:EndArrayPlugin; | ||
| 79 | |||
| 80 | /** @private **/ | ||
| 81 | public function ColorMatrixFilterPlugin() { | ||
| 82 | super(); | ||
| 83 | this.propName = "colorMatrixFilter"; | ||
| 84 | this.overwriteProps = ["colorMatrixFilter"]; | ||
| 85 | } | ||
| 86 | |||
| 87 | /** @private **/ | ||
| 88 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 89 | _target = target; | ||
| 90 | _type = ColorMatrixFilter; | ||
| 91 | var cmf:Object = value; | ||
| 92 | initFilter({remove:value.remove, index:value.index, addFilter:value.addFilter}, new ColorMatrixFilter(_idMatrix.slice()), _propNames); | ||
| 93 | _matrix = ColorMatrixFilter(_filter).matrix; | ||
| 94 | var endMatrix:Array = []; | ||
| 95 | if (cmf.matrix != null && (cmf.matrix is Array)) { | ||
| 96 | endMatrix = cmf.matrix; | ||
| 97 | } else { | ||
| 98 | if (cmf.relative == true) { | ||
| 99 | endMatrix = _matrix.slice(); | ||
| 100 | } else { | ||
| 101 | endMatrix = _idMatrix.slice(); | ||
| 102 | } | ||
| 103 | endMatrix = setBrightness(endMatrix, cmf.brightness); | ||
| 104 | endMatrix = setContrast(endMatrix, cmf.contrast); | ||
| 105 | endMatrix = setHue(endMatrix, cmf.hue); | ||
| 106 | endMatrix = setSaturation(endMatrix, cmf.saturation); | ||
| 107 | endMatrix = setThreshold(endMatrix, cmf.threshold); | ||
| 108 | if (!isNaN(cmf.colorize)) { | ||
| 109 | endMatrix = colorize(endMatrix, cmf.colorize, cmf.amount); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | _matrixTween = new EndArrayPlugin(); | ||
| 113 | _matrixTween.init(_matrix, endMatrix); | ||
| 114 | return true; | ||
| 115 | } | ||
| 116 | |||
| 117 | /** @private **/ | ||
| 118 | override public function set changeFactor(n:Number):void { | ||
| 119 | _matrixTween.changeFactor = n; | ||
| 120 | ColorMatrixFilter(_filter).matrix = _matrix; | ||
| 121 | super.changeFactor = n; | ||
| 122 | } | ||
| 123 | |||
| 124 | |||
| 125 | //---- MATRIX OPERATIONS -------------------------------------------------------------------------------- | ||
| 126 | |||
| 127 | /** @private **/ | ||
| 128 | public static function colorize(m:Array, color:Number, amount:Number = 1):Array { | ||
| 129 | if (isNaN(color)) { | ||
| 130 | return m; | ||
| 131 | } else if (isNaN(amount)) { | ||
| 132 | amount = 1; | ||
| 133 | } | ||
| 134 | var r:Number = ((color >> 16) & 0xff) / 255; | ||
| 135 | var g:Number = ((color >> 8) & 0xff) / 255; | ||
| 136 | var b:Number = (color & 0xff) / 255; | ||
| 137 | var inv:Number = 1 - amount; | ||
| 138 | var temp:Array = [inv + amount * r * _lumR, amount * r * _lumG, amount * r * _lumB, 0, 0, | ||
| 139 | amount * g * _lumR, inv + amount * g * _lumG, amount * g * _lumB, 0, 0, | ||
| 140 | amount * b * _lumR, amount * b * _lumG, inv + amount * b * _lumB, 0, 0, | ||
| 141 | 0, 0, 0, 1, 0]; | ||
| 142 | return applyMatrix(temp, m); | ||
| 143 | } | ||
| 144 | |||
| 145 | /** @private **/ | ||
| 146 | public static function setThreshold(m:Array, n:Number):Array { | ||
| 147 | if (isNaN(n)) { | ||
| 148 | return m; | ||
| 149 | } | ||
| 150 | var temp:Array = [_lumR * 256, _lumG * 256, _lumB * 256, 0, -256 * n, | ||
| 151 | _lumR * 256, _lumG * 256, _lumB * 256, 0, -256 * n, | ||
| 152 | _lumR * 256, _lumG * 256, _lumB * 256, 0, -256 * n, | ||
| 153 | 0, 0, 0, 1, 0]; | ||
| 154 | return applyMatrix(temp, m); | ||
| 155 | } | ||
| 156 | |||
| 157 | /** @private **/ | ||
| 158 | public static function setHue(m:Array, n:Number):Array { | ||
| 159 | if (isNaN(n)) { | ||
| 160 | return m; | ||
| 161 | } | ||
| 162 | n *= Math.PI / 180; | ||
| 163 | var c:Number = Math.cos(n); | ||
| 164 | var s:Number = Math.sin(n); | ||
| 165 | var temp:Array = [(_lumR + (c * (1 - _lumR))) + (s * (-_lumR)), (_lumG + (c * (-_lumG))) + (s * (-_lumG)), (_lumB + (c * (-_lumB))) + (s * (1 - _lumB)), 0, 0, (_lumR + (c * (-_lumR))) + (s * 0.143), (_lumG + (c * (1 - _lumG))) + (s * 0.14), (_lumB + (c * (-_lumB))) + (s * -0.283), 0, 0, (_lumR + (c * (-_lumR))) + (s * (-(1 - _lumR))), (_lumG + (c * (-_lumG))) + (s * _lumG), (_lumB + (c * (1 - _lumB))) + (s * _lumB), 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]; | ||
| 166 | return applyMatrix(temp, m); | ||
| 167 | } | ||
| 168 | |||
| 169 | /** @private **/ | ||
| 170 | public static function setBrightness(m:Array, n:Number):Array { | ||
| 171 | if (isNaN(n)) { | ||
| 172 | return m; | ||
| 173 | } | ||
| 174 | n = (n * 100) - 100; | ||
| 175 | return applyMatrix([1,0,0,0,n, | ||
| 176 | 0,1,0,0,n, | ||
| 177 | 0,0,1,0,n, | ||
| 178 | 0,0,0,1,0, | ||
| 179 | 0,0,0,0,1], m); | ||
| 180 | } | ||
| 181 | |||
| 182 | /** @private **/ | ||
| 183 | public static function setSaturation(m:Array, n:Number):Array { | ||
| 184 | if (isNaN(n)) { | ||
| 185 | return m; | ||
| 186 | } | ||
| 187 | var inv:Number = 1 - n; | ||
| 188 | var r:Number = inv * _lumR; | ||
| 189 | var g:Number = inv * _lumG; | ||
| 190 | var b:Number = inv * _lumB; | ||
| 191 | var temp:Array = [r + n, g , b , 0, 0, | ||
| 192 | r , g + n, b , 0, 0, | ||
| 193 | r , g , b + n, 0, 0, | ||
| 194 | 0 , 0 , 0 , 1, 0]; | ||
| 195 | return applyMatrix(temp, m); | ||
| 196 | } | ||
| 197 | |||
| 198 | /** @private **/ | ||
| 199 | public static function setContrast(m:Array, n:Number):Array { | ||
| 200 | if (isNaN(n)) { | ||
| 201 | return m; | ||
| 202 | } | ||
| 203 | n += 0.01; | ||
| 204 | var temp:Array = [n,0,0,0,128 * (1 - n), | ||
| 205 | 0,n,0,0,128 * (1 - n), | ||
| 206 | 0,0,n,0,128 * (1 - n), | ||
| 207 | 0,0,0,1,0]; | ||
| 208 | return applyMatrix(temp, m); | ||
| 209 | } | ||
| 210 | |||
| 211 | /** @private **/ | ||
| 212 | public static function applyMatrix(m:Array, m2:Array):Array { | ||
| 213 | if (!(m is Array) || !(m2 is Array)) { | ||
| 214 | return m2; | ||
| 215 | } | ||
| 216 | var temp:Array = [], i:int = 0, z:int = 0, y:int, x:int; | ||
| 217 | for (y = 0; y < 4; y++) { | ||
| 218 | for (x = 0; x < 5; x++) { | ||
| 219 | if (x == 4) { | ||
| 220 | z = m[i + 4]; | ||
| 221 | } else { | ||
| 222 | z = 0; | ||
| 223 | } | ||
| 224 | temp[i + x] = m[i] * m2[x] + | ||
| 225 | m[i+1] * m2[x + 5] + | ||
| 226 | m[i+2] * m2[x + 10] + | ||
| 227 | m[i+3] * m2[x + 15] + | ||
| 228 | z; | ||
| 229 | } | ||
| 230 | i += 5; | ||
| 231 | } | ||
| 232 | return temp; | ||
| 233 | } | ||
| 234 | |||
| 235 | } | ||
| 236 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.52 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import flash.geom.ColorTransform; | ||
| 10 | import com.greensock.*; | ||
| 11 | /** | ||
| 12 | * Ever wanted to tween ColorTransform properties of a DisplayObject to do advanced effects like overexposing, altering | ||
| 13 | * the brightness or setting the percent/amount of tint? Or maybe tween individual ColorTransform | ||
| 14 | * properties like redMultiplier, redOffset, blueMultiplier, blueOffset, etc. ColorTransformPlugin gives you an easy way to | ||
| 15 | * do just that. <br /><br /> | ||
| 16 | * | ||
| 17 | * <b>PROPERTIES:</b><br /> | ||
| 18 | * <ul> | ||
| 19 | * <li><code> tint (or color) : uint</code> - Color of the tint. Use a hex value, like 0xFF0000 for red.</li> | ||
| 20 | * <li><code> tintAmount : Number</code> - Number between 0 and 1. Works with the "tint" property and indicats how much of an effect the tint should have. 0 makes the tint invisible, 0.5 is halfway tinted, and 1 is completely tinted.</li> | ||
| 21 | * <li><code> brightness : Number</code> - Number between 0 and 2 where 1 is normal brightness, 0 is completely dark/black, and 2 is completely bright/white</li> | ||
| 22 | * <li><code> exposure : Number</code> - Number between 0 and 2 where 1 is normal exposure, 0, is completely underexposed, and 2 is completely overexposed. Overexposing an object is different then changing the brightness - it seems to almost bleach the image and looks more dynamic and interesting (subjectively speaking).</li> | ||
| 23 | * <li><code> redOffset : Number</code></li> | ||
| 24 | * <li><code> greenOffset : Number</code></li> | ||
| 25 | * <li><code> blueOffset : Number</code></li> | ||
| 26 | * <li><code> alphaOffset : Number</code></li> | ||
| 27 | * <li><code> redMultiplier : Number</code></li> | ||
| 28 | * <li><code> greenMultiplier : Number</code></li> | ||
| 29 | * <li><code> blueMultiplier : Number</code></li> | ||
| 30 | * <li><code> alphaMultiplier : Number</code> </li> | ||
| 31 | * </ul><br /><br /> | ||
| 32 | * | ||
| 33 | * <b>USAGE:</b><br /><br /> | ||
| 34 | * <code> | ||
| 35 | * import com.greensock.TweenLite; <br /> | ||
| 36 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 37 | * import com.greensock.plugins.ColorTransformPlugin; <br /> | ||
| 38 | * TweenPlugin.activate([ColorTransformPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 39 | * | ||
| 40 | * TweenLite.to(mc, 1, {colorTransform:{tint:0xFF0000, tintAmount:0.5}}); <br /><br /> | ||
| 41 | * </code> | ||
| 42 | * | ||
| 43 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 44 | * | ||
| 45 | * @author Jack Doyle, jack@greensock.com | ||
| 46 | */ | ||
| 47 | public class ColorTransformPlugin extends TintPlugin { | ||
| 48 | /** @private **/ | ||
| 49 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 50 | |||
| 51 | /** @private **/ | ||
| 52 | public function ColorTransformPlugin() { | ||
| 53 | super(); | ||
| 54 | this.propName = "colorTransform"; | ||
| 55 | } | ||
| 56 | |||
| 57 | /** @private **/ | ||
| 58 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 59 | if (!(target is DisplayObject)) { | ||
| 60 | return false; | ||
| 61 | } | ||
| 62 | var end:ColorTransform = target.transform.colorTransform; | ||
| 63 | for (var p:String in value) { | ||
| 64 | if (p == "tint" || p == "color") { | ||
| 65 | if (value[p] != null) { | ||
| 66 | end.color = int(value[p]); | ||
| 67 | } | ||
| 68 | } else if (p == "tintAmount" || p == "exposure" || p == "brightness") { | ||
| 69 | //handle this later... | ||
| 70 | } else { | ||
| 71 | end[p] = value[p]; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | if (!isNaN(value.tintAmount)) { | ||
| 76 | var ratio:Number = value.tintAmount / (1 - ((end.redMultiplier + end.greenMultiplier + end.blueMultiplier) / 3)); | ||
| 77 | end.redOffset *= ratio; | ||
| 78 | end.greenOffset *= ratio; | ||
| 79 | end.blueOffset *= ratio; | ||
| 80 | end.redMultiplier = end.greenMultiplier = end.blueMultiplier = 1 - value.tintAmount; | ||
| 81 | } else if (!isNaN(value.exposure)) { | ||
| 82 | end.redOffset = end.greenOffset = end.blueOffset = 255 * (value.exposure - 1); | ||
| 83 | end.redMultiplier = end.greenMultiplier = end.blueMultiplier = 1; | ||
| 84 | } else if (!isNaN(value.brightness)) { | ||
| 85 | end.redOffset = end.greenOffset = end.blueOffset = Math.max(0, (value.brightness - 1) * 255); | ||
| 86 | end.redMultiplier = end.greenMultiplier = end.blueMultiplier = 1 - Math.abs(value.brightness - 1); | ||
| 87 | } | ||
| 88 | |||
| 89 | _ignoreAlpha = Boolean(tween.vars.alpha != undefined && value.alphaMultiplier == undefined); | ||
| 90 | |||
| 91 | init(target as DisplayObject, end); | ||
| 92 | |||
| 93 | return true; | ||
| 94 | } | ||
| 95 | |||
| 96 | } | ||
| 97 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.0 | ||
| 3 | * DATE: 8/18/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.filters.*; | ||
| 9 | import flash.display.*; | ||
| 10 | import com.greensock.*; | ||
| 11 | /** | ||
| 12 | * Tweens a DropShadowFilter. The following properties are available (you only need to define the ones you want to tween): | ||
| 13 | * <code> | ||
| 14 | * <ul> | ||
| 15 | * <li> distance : Number [0]</li> | ||
| 16 | * <li> angle : Number [45]</li> | ||
| 17 | * <li> color : uint [0x000000]</li> | ||
| 18 | * <li> alpha :Number [0]</li> | ||
| 19 | * <li> blurX : Number [0]</li> | ||
| 20 | * <li> blurY : Number [0]</li> | ||
| 21 | * <li> strength : Number [1]</li> | ||
| 22 | * <li> quality : uint [2]</li> | ||
| 23 | * <li> inner : Boolean [false]</li> | ||
| 24 | * <li> knockout : Boolean [false]</li> | ||
| 25 | * <li> hideObject : Boolean [false]</li> | ||
| 26 | * <li> index : uint</li> | ||
| 27 | * <li> addFilter : Boolean [false]</li> | ||
| 28 | * <li> remove : Boolean [false]</li> | ||
| 29 | * </ul> | ||
| 30 | * </code> | ||
| 31 | * Set <code>remove</code> to true if you want the filter to be removed when the tween completes. <br /><br /> | ||
| 32 | * | ||
| 33 | * <b>USAGE:</b><br /><br /> | ||
| 34 | * <code> | ||
| 35 | * import com.greensock.TweenLite; <br /> | ||
| 36 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 37 | * import com.greensock.plugins.DropShadowFilterPlugin; <br /> | ||
| 38 | * TweenPlugin.activate([DropShadowFilterPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 39 | * | ||
| 40 | * TweenLite.to(mc, 1, {dropShadowFilter:{blurX:5, blurY:5, distance:5, alpha:0.6}}); <br /><br /> | ||
| 41 | * </code> | ||
| 42 | * | ||
| 43 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 44 | * | ||
| 45 | * @author Jack Doyle, jack@greensock.com | ||
| 46 | */ | ||
| 47 | public class DropShadowFilterPlugin extends FilterPlugin { | ||
| 48 | /** @private **/ | ||
| 49 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 50 | /** @private **/ | ||
| 51 | private static var _propNames:Array = ["distance","angle","color","alpha","blurX","blurY","strength","quality","inner","knockout","hideObject"]; | ||
| 52 | |||
| 53 | /** @private **/ | ||
| 54 | public function DropShadowFilterPlugin() { | ||
| 55 | super(); | ||
| 56 | this.propName = "dropShadowFilter"; | ||
| 57 | this.overwriteProps = ["dropShadowFilter"]; | ||
| 58 | } | ||
| 59 | |||
| 60 | /** @private **/ | ||
| 61 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 62 | _target = target; | ||
| 63 | _type = DropShadowFilter; | ||
| 64 | initFilter(value, new DropShadowFilter(0, 45, 0x000000, 0, 0, 0, 1, value.quality || 2, value.inner, value.knockout, value.hideObject), _propNames); | ||
| 65 | return true; | ||
| 66 | } | ||
| 67 | |||
| 68 | } | ||
| 69 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.6 | ||
| 3 | * DATE: 10/19/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.*; | ||
| 11 | /** | ||
| 12 | * Tweens numbers in an Array. <br /><br /> | ||
| 13 | * | ||
| 14 | * <b>USAGE:</b><br /><br /> | ||
| 15 | * <code> | ||
| 16 | * import com.greensock.TweenLite; <br /> | ||
| 17 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 18 | * import com.greensock.plugins.EndArrayPlugin; <br /> | ||
| 19 | * TweenPlugin.activate([EndArrayPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 20 | * | ||
| 21 | * var myArray:Array = [1,2,3,4];<br /> | ||
| 22 | * TweenLite.to(myArray, 1.5, {endArray:[10,20,30,40]}); <br /><br /> | ||
| 23 | * </code> | ||
| 24 | * | ||
| 25 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 26 | * | ||
| 27 | * @author Jack Doyle, jack@greensock.com | ||
| 28 | */ | ||
| 29 | public class EndArrayPlugin extends TweenPlugin { | ||
| 30 | /** @private **/ | ||
| 31 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 32 | |||
| 33 | /** @private **/ | ||
| 34 | protected var _a:Array; | ||
| 35 | /** @private **/ | ||
| 36 | protected var _info:Array = []; | ||
| 37 | |||
| 38 | /** @private **/ | ||
| 39 | public function EndArrayPlugin() { | ||
| 40 | super(); | ||
| 41 | this.propName = "endArray"; //name of the special property that the plugin should intercept/manage | ||
| 42 | this.overwriteProps = ["endArray"]; | ||
| 43 | } | ||
| 44 | |||
| 45 | /** @private **/ | ||
| 46 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 47 | if (!(target is Array) || !(value is Array)) { | ||
| 48 | return false; | ||
| 49 | } | ||
| 50 | init(target as Array, value); | ||
| 51 | return true; | ||
| 52 | } | ||
| 53 | |||
| 54 | /** @private **/ | ||
| 55 | public function init(start:Array, end:Array):void { | ||
| 56 | _a = start; | ||
| 57 | var i:int = end.length; | ||
| 58 | while (i--) { | ||
| 59 | if (start[i] != end[i] && start[i] != null) { | ||
| 60 | _info[_info.length] = new ArrayTweenInfo(i, _a[i], end[i] - _a[i]); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | /** @private **/ | ||
| 66 | override public function set changeFactor(n:Number):void { | ||
| 67 | var i:int = _info.length, ti:ArrayTweenInfo; | ||
| 68 | if (this.round) { | ||
| 69 | var val:Number; | ||
| 70 | while (i--) { | ||
| 71 | ti = _info[i]; | ||
| 72 | val = ti.start + (ti.change * n); | ||
| 73 | _a[ti.index] = (val > 0) ? int(val + 0.5) : int(val - 0.5); //4 times as fast as Math.round() | ||
| 74 | } | ||
| 75 | } else { | ||
| 76 | while (i--) { | ||
| 77 | ti = _info[i]; | ||
| 78 | _a[ti.index] = ti.start + (ti.change * n); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | internal class ArrayTweenInfo { | ||
| 87 | public var index:uint; | ||
| 88 | public var start:Number; | ||
| 89 | public var change:Number; | ||
| 90 | |||
| 91 | public function ArrayTweenInfo(index:uint, start:Number, change:Number) { | ||
| 92 | this.index = index; | ||
| 93 | this.start = start; | ||
| 94 | this.change = change; | ||
| 95 | } | ||
| 96 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.9 | ||
| 3 | * DATE: 10/22/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://blog.greensock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.*; | ||
| 11 | /** | ||
| 12 | * Tweens numbers in an Vector.<Number>. Remember, Vectors require that you publish to <strong>Flash Player 10</strong> or later.<br /><br /> | ||
| 13 | * | ||
| 14 | * <b>USAGE:</b><br /><br /> | ||
| 15 | * <code> | ||
| 16 | * import com.greensock.TweenLite; <br /> | ||
| 17 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 18 | * import com.greensock.plugins.EndVectorPlugin; <br /> | ||
| 19 | * TweenPlugin.activate([EndVectorPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 20 | * | ||
| 21 | * var v:Vector.<Number> = new Vector.<Number>();<br /> | ||
| 22 | * v[0] = 0;<br /> | ||
| 23 | * v[1] = 1;<br /> | ||
| 24 | * v[2] = 2;<br /> | ||
| 25 | * var end:Vector.<Number> = new Vector.<Number>();<br /> | ||
| 26 | * end[0] = 100;<br /> | ||
| 27 | * end[1] = 250;<br /> | ||
| 28 | * end[2] = 500;<br /> | ||
| 29 | * TweenLite.to(v, 3, {endVector:end, onUpdate:report}); <br /> | ||
| 30 | * function report():void {<br /> | ||
| 31 | * trace(v);<br /> | ||
| 32 | * }<br /><br /> | ||
| 33 | * </code> | ||
| 34 | * | ||
| 35 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 36 | * | ||
| 37 | * @author Jack Doyle, jack@greensock.com | ||
| 38 | */ | ||
| 39 | public class EndVectorPlugin extends TweenPlugin { | ||
| 40 | /** @private **/ | ||
| 41 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 42 | |||
| 43 | /** @private **/ | ||
| 44 | protected var _v:Vector.<Number>; | ||
| 45 | /** @private **/ | ||
| 46 | protected var _info:Vector.<VectorInfo> = new Vector.<VectorInfo>(); | ||
| 47 | |||
| 48 | /** @private **/ | ||
| 49 | public function EndVectorPlugin() { | ||
| 50 | super(); | ||
| 51 | this.propName = "endVector"; //name of the special property that the plugin should intercept/manage | ||
| 52 | this.overwriteProps = ["endVector"]; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** @private **/ | ||
| 56 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 57 | if (!(target is Vector.<Number>) || !(value is Vector.<Number>)) { | ||
| 58 | return false; | ||
| 59 | } | ||
| 60 | init(target as Vector.<Number>, value as Vector.<Number>); | ||
| 61 | return true; | ||
| 62 | } | ||
| 63 | |||
| 64 | /** @private **/ | ||
| 65 | public function init(start:Vector.<Number>, end:Vector.<Number>):void { | ||
| 66 | _v = start; | ||
| 67 | var i:int = end.length, cnt:uint = 0; | ||
| 68 | while (i--) { | ||
| 69 | if (_v[i] != end[i]) { | ||
| 70 | _info[cnt++] = new VectorInfo(i, _v[i], end[i] - _v[i]); | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | /** @private **/ | ||
| 76 | override public function set changeFactor(n:Number):void { | ||
| 77 | var i:int = _info.length, vi:VectorInfo; | ||
| 78 | if (this.round) { | ||
| 79 | var val:Number; | ||
| 80 | while (i--) { | ||
| 81 | vi = _info[i]; | ||
| 82 | val = vi.start + (vi.change * n); | ||
| 83 | _v[vi.index] = (val > 0) ? int(val + 0.5) : int(val - 0.5); //4 times as fast as Math.round() | ||
| 84 | } | ||
| 85 | } else { | ||
| 86 | while (i--) { | ||
| 87 | vi = _info[i]; | ||
| 88 | _v[vi.index] = vi.start + (vi.change * n); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | internal class VectorInfo { | ||
| 97 | public var index:uint; | ||
| 98 | public var start:Number; | ||
| 99 | public var change:Number; | ||
| 100 | |||
| 101 | public function VectorInfo(index:uint, start:Number, change:Number) { | ||
| 102 | this.index = index; | ||
| 103 | this.start = start; | ||
| 104 | this.change = change; | ||
| 105 | } | ||
| 106 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.03 | ||
| 3 | * DATE: 10/22/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | import com.greensock.core.*; | ||
| 10 | |||
| 11 | import flash.display.*; | ||
| 12 | import flash.filters.*; | ||
| 13 | /** | ||
| 14 | * Base class for all filter plugins (like blurFilter, colorMatrixFilter, glowFilter, etc.). Handles common routines. | ||
| 15 | * There is no reason to use this class directly.<br /><br /> | ||
| 16 | * | ||
| 17 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 18 | * | ||
| 19 | * @author Jack Doyle, jack@greensock.com | ||
| 20 | */ | ||
| 21 | public class FilterPlugin extends TweenPlugin { | ||
| 22 | /** @private **/ | ||
| 23 | public static const VERSION:Number = 2.03; | ||
| 24 | /** @private **/ | ||
| 25 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 26 | |||
| 27 | /** @private **/ | ||
| 28 | protected var _target:Object; | ||
| 29 | /** @private **/ | ||
| 30 | protected var _type:Class; | ||
| 31 | /** @private **/ | ||
| 32 | protected var _filter:BitmapFilter; | ||
| 33 | /** @private **/ | ||
| 34 | protected var _index:int; | ||
| 35 | /** @private **/ | ||
| 36 | protected var _remove:Boolean; | ||
| 37 | |||
| 38 | /** @private **/ | ||
| 39 | public function FilterPlugin() { | ||
| 40 | super(); | ||
| 41 | } | ||
| 42 | |||
| 43 | /** @private **/ | ||
| 44 | protected function initFilter(props:Object, defaultFilter:BitmapFilter, propNames:Array):void { | ||
| 45 | var filters:Array = _target.filters, p:String, i:int, colorTween:HexColorsPlugin; | ||
| 46 | var extras:Object = (props is BitmapFilter) ? {} : props; | ||
| 47 | _index = -1; | ||
| 48 | if (extras.index != null) { | ||
| 49 | _index = extras.index; | ||
| 50 | } else { | ||
| 51 | i = filters.length; | ||
| 52 | while (i--) { | ||
| 53 | if (filters[i] is _type) { | ||
| 54 | _index = i; | ||
| 55 | break; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | if (_index == -1 || filters[_index] == null || extras.addFilter == true) { | ||
| 60 | _index = (extras.index != null) ? extras.index : filters.length; | ||
| 61 | filters[_index] = defaultFilter; | ||
| 62 | _target.filters = filters; | ||
| 63 | } | ||
| 64 | _filter = filters[_index]; | ||
| 65 | |||
| 66 | if (extras.remove == true) { | ||
| 67 | _remove = true; | ||
| 68 | this.onComplete = onCompleteTween; | ||
| 69 | } | ||
| 70 | i = propNames.length; | ||
| 71 | while (i--) { | ||
| 72 | p = propNames[i]; | ||
| 73 | if (p in props && _filter[p] != props[p]) { | ||
| 74 | if (p == "color" || p == "highlightColor" || p == "shadowColor") { | ||
| 75 | colorTween = new HexColorsPlugin(); | ||
| 76 | colorTween.initColor(_filter, p, _filter[p], props[p]); | ||
| 77 | _tweens[_tweens.length] = new PropTween(colorTween, "changeFactor", 0, 1, p, false); | ||
| 78 | } else if (p == "quality" || p == "inner" || p == "knockout" || p == "hideObject") { | ||
| 79 | _filter[p] = props[p]; | ||
| 80 | } else { | ||
| 81 | addTween(_filter, p, _filter[p], props[p], p); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | /** @private **/ | ||
| 88 | public function onCompleteTween():void { | ||
| 89 | if (_remove) { | ||
| 90 | var filters:Array = _target.filters; | ||
| 91 | if (!(filters[_index] is _type)) { //a filter may have been added or removed since the tween began, changing the index. | ||
| 92 | var i:int = filters.length; | ||
| 93 | while (i--) { | ||
| 94 | if (filters[i] is _type) { | ||
| 95 | filters.splice(i, 1); | ||
| 96 | break; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | } else { | ||
| 100 | filters.splice(_index, 1); | ||
| 101 | } | ||
| 102 | _target.filters = filters; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | /** @private **/ | ||
| 107 | override public function set changeFactor(n:Number):void { | ||
| 108 | var i:int = _tweens.length, ti:PropTween, filters:Array = _target.filters; | ||
| 109 | while (i--) { | ||
| 110 | ti = _tweens[i]; | ||
| 111 | ti.target[ti.property] = ti.start + (ti.change * n); | ||
| 112 | } | ||
| 113 | |||
| 114 | if (!(filters[_index] is _type)) { //a filter may have been added or removed since the tween began, changing the index. | ||
| 115 | i = _index = filters.length; //default (in case it was removed) | ||
| 116 | while (i--) { | ||
| 117 | if (filters[i] is _type) { | ||
| 118 | _index = i; | ||
| 119 | break; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | filters[_index] = _filter; | ||
| 124 | _target.filters = filters; | ||
| 125 | } | ||
| 126 | |||
| 127 | } | ||
| 128 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.1 | ||
| 3 | * DATE: 2010-04-17 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | |||
| 9 | /** | ||
| 10 | * Tweens a MovieClip backward to a particular frame number, wrapping it if/when it reaches the beginning | ||
| 11 | * of the timeline. For example, if your MovieClip has 20 frames total and it is currently at frame 10 | ||
| 12 | * and you want tween to frame 15, a normal frame tween would go forward from 10 to 15, but a frameBackward | ||
| 13 | * would go from 10 to 1 (the beginning) and wrap to the end and continue tweening from 20 to 15. <br /><br /> | ||
| 14 | * | ||
| 15 | * <b>USAGE:</b><br /><br /> | ||
| 16 | * <code> | ||
| 17 | * import com.greensock.TweenLite; <br /> | ||
| 18 | * import com.greensock.plugins.~~; <br /> | ||
| 19 | * TweenPlugin.activate([FrameBackwardPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 20 | * | ||
| 21 | * TweenLite.to(mc, 1, {frameBackward:15}); <br /><br /> | ||
| 22 | * </code> | ||
| 23 | * | ||
| 24 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 25 | * | ||
| 26 | * @author Jack Doyle, jack@greensock.com | ||
| 27 | */ | ||
| 28 | public class FrameBackwardPlugin extends FrameForwardPlugin { | ||
| 29 | /** @private **/ | ||
| 30 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 31 | |||
| 32 | /** @private **/ | ||
| 33 | public function FrameBackwardPlugin() { | ||
| 34 | super(); | ||
| 35 | this.propName = "frameBackward"; | ||
| 36 | _backward = true; | ||
| 37 | } | ||
| 38 | |||
| 39 | } | ||
| 40 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.1 | ||
| 3 | * DATE: 2010-04-17 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.*; | ||
| 11 | /** | ||
| 12 | * Tweens a MovieClip forward to a particular frame number, wrapping it if/when it reaches the end | ||
| 13 | * of the timeline. For example, if your MovieClip has 20 frames total and it is currently at frame 10 | ||
| 14 | * and you want tween to frame 5, a normal frame tween would go backwards from 10 to 5, but a frameForward | ||
| 15 | * would go from 10 to 20 (the end) and wrap to the beginning and continue tweening from 1 to 5. <br /><br /> | ||
| 16 | * | ||
| 17 | * <b>USAGE:</b><br /><br /> | ||
| 18 | * <code> | ||
| 19 | * import com.greensock.TweenLite; <br /> | ||
| 20 | * import com.greensock.plugins.~~; <br /> | ||
| 21 | * TweenPlugin.activate([FrameForwardPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 22 | * | ||
| 23 | * TweenLite.to(mc, 1, {frameForward:5}); <br /><br /> | ||
| 24 | * </code> | ||
| 25 | * | ||
| 26 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 27 | * | ||
| 28 | * @author Jack Doyle, jack@greensock.com | ||
| 29 | */ | ||
| 30 | public class FrameForwardPlugin extends TweenPlugin { | ||
| 31 | /** @private **/ | ||
| 32 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 33 | |||
| 34 | /** @private **/ | ||
| 35 | protected var _start:int; | ||
| 36 | /** @private **/ | ||
| 37 | protected var _change:int; | ||
| 38 | /** @private **/ | ||
| 39 | protected var _max:uint; | ||
| 40 | /** @private **/ | ||
| 41 | protected var _target:MovieClip; | ||
| 42 | /** @private Allows FrameBackwardPlugin to extend this class and only use an extremely small amount of kb (because the functionality is combined here) **/ | ||
| 43 | protected var _backward:Boolean; | ||
| 44 | |||
| 45 | /** @private **/ | ||
| 46 | public function FrameForwardPlugin() { | ||
| 47 | super(); | ||
| 48 | this.propName = "frameForward"; | ||
| 49 | this.overwriteProps = ["frame","frameLabel","frameForward","frameBackward"]; | ||
| 50 | this.round = true; | ||
| 51 | } | ||
| 52 | |||
| 53 | /** @private **/ | ||
| 54 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 55 | if (!(target is MovieClip) || isNaN(value)) { | ||
| 56 | return false; | ||
| 57 | } | ||
| 58 | _target = target as MovieClip; | ||
| 59 | _start = _target.currentFrame; | ||
| 60 | _max = _target.totalFrames; | ||
| 61 | _change = (typeof(value) == "number") ? Number(value) - _start : Number(value); | ||
| 62 | if (!_backward && _change < 0) { | ||
| 63 | _change += _max; | ||
| 64 | } else if (_backward && _change > 0) { | ||
| 65 | _change -= _max; | ||
| 66 | } | ||
| 67 | return true; | ||
| 68 | } | ||
| 69 | |||
| 70 | /** @private **/ | ||
| 71 | override public function set changeFactor(n:Number):void { | ||
| 72 | var frame:Number = (_start + (_change * n)) % _max; | ||
| 73 | if (frame < 0.5 && frame >= -0.5) { | ||
| 74 | frame = _max; | ||
| 75 | } else if (frame < 0) { | ||
| 76 | frame += _max; | ||
| 77 | } | ||
| 78 | _target.gotoAndStop( int(frame + 0.5) ); | ||
| 79 | } | ||
| 80 | |||
| 81 | } | ||
| 82 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.03 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.*; | ||
| 11 | /** | ||
| 12 | * Tweens a MovieClip to a particular frame label. <br /><br /> | ||
| 13 | * | ||
| 14 | * <b>USAGE:</b><br /><br /> | ||
| 15 | * <code> | ||
| 16 | * import com.greensock.TweenLite; <br /> | ||
| 17 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 18 | * import com.greensock.plugins.FrameLabelPlugin; <br /> | ||
| 19 | * TweenPlugin.activate([FrameLabelPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 20 | * | ||
| 21 | * TweenLite.to(mc, 1, {frameLabel:"myLabel"}); <br /><br /> | ||
| 22 | * </code> | ||
| 23 | * | ||
| 24 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 25 | * | ||
| 26 | * @author Jack Doyle, jack@greensock.com | ||
| 27 | */ | ||
| 28 | public class FrameLabelPlugin extends FramePlugin { | ||
| 29 | /** @private **/ | ||
| 30 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 31 | |||
| 32 | /** @private **/ | ||
| 33 | public function FrameLabelPlugin() { | ||
| 34 | super(); | ||
| 35 | this.propName = "frameLabel"; | ||
| 36 | } | ||
| 37 | |||
| 38 | /** @private **/ | ||
| 39 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 40 | if (!tween.target is MovieClip) { | ||
| 41 | return false; | ||
| 42 | } | ||
| 43 | _target = target as MovieClip; | ||
| 44 | this.frame = _target.currentFrame; | ||
| 45 | var labels:Array = _target.currentLabels, label:String = value, endFrame:int = _target.currentFrame; | ||
| 46 | var i:int = labels.length; | ||
| 47 | while (i--) { | ||
| 48 | if (labels[i].name == label) { | ||
| 49 | endFrame = labels[i].frame; | ||
| 50 | break; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | if (this.frame != endFrame) { | ||
| 54 | addTween(this, "frame", this.frame, endFrame, "frame"); | ||
| 55 | } | ||
| 56 | return true; | ||
| 57 | } | ||
| 58 | |||
| 59 | |||
| 60 | } | ||
| 61 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.03 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import com.greensock.*; | ||
| 10 | /** | ||
| 11 | * Tweens a MovieClip to a particular frame number. <br /><br /> | ||
| 12 | * | ||
| 13 | * <b>USAGE:</b><br /><br /> | ||
| 14 | * <code> | ||
| 15 | * import com.greensock.TweenLite; <br /> | ||
| 16 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 17 | * import com.greensock.plugins.FramePlugin; <br /> | ||
| 18 | * TweenPlugin.activate([FramePlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 19 | * | ||
| 20 | * TweenLite.to(mc, 1, {frame:125}); <br /><br /> | ||
| 21 | * </code> | ||
| 22 | * | ||
| 23 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 24 | * | ||
| 25 | * @author Jack Doyle, jack@greensock.com | ||
| 26 | */ | ||
| 27 | public class FramePlugin extends TweenPlugin { | ||
| 28 | /** @private **/ | ||
| 29 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 30 | |||
| 31 | /** @private **/ | ||
| 32 | public var frame:int; | ||
| 33 | /** @private **/ | ||
| 34 | protected var _target:MovieClip; | ||
| 35 | |||
| 36 | /** @private **/ | ||
| 37 | public function FramePlugin() { | ||
| 38 | super(); | ||
| 39 | this.propName = "frame"; | ||
| 40 | this.overwriteProps = ["frame","frameLabel"]; | ||
| 41 | this.round = true; | ||
| 42 | } | ||
| 43 | |||
| 44 | /** @private **/ | ||
| 45 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 46 | if (!(target is MovieClip) || isNaN(value)) { | ||
| 47 | return false; | ||
| 48 | } | ||
| 49 | _target = target as MovieClip; | ||
| 50 | this.frame = _target.currentFrame; | ||
| 51 | addTween(this, "frame", this.frame, value, "frame"); | ||
| 52 | return true; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** @private **/ | ||
| 56 | override public function set changeFactor(n:Number):void { | ||
| 57 | updateTweens(n); | ||
| 58 | _target.gotoAndStop(this.frame); | ||
| 59 | } | ||
| 60 | |||
| 61 | } | ||
| 62 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.0 | ||
| 3 | * DATE: 8/18/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.filters.*; | ||
| 9 | import flash.display.*; | ||
| 10 | import com.greensock.*; | ||
| 11 | /** | ||
| 12 | * Tweens a GlowFilter. The following properties are available (you only need to define the ones you want to tween): | ||
| 13 | * <code> | ||
| 14 | * <ul> | ||
| 15 | * <li> color : uint [0x000000]</li> | ||
| 16 | * <li> alpha :Number [0]</li> | ||
| 17 | * <li> blurX : Number [0]</li> | ||
| 18 | * <li> blurY : Number [0]</li> | ||
| 19 | * <li> strength : Number [1]</li> | ||
| 20 | * <li> quality : uint [2]</li> | ||
| 21 | * <li> inner : Boolean [false]</li> | ||
| 22 | * <li> knockout : Boolean [false]</li> | ||
| 23 | * <li> index : uint</li> | ||
| 24 | * <li> addFilter : Boolean [false]</li> | ||
| 25 | * <li> remove : Boolean [false]</li> | ||
| 26 | * </ul> | ||
| 27 | * </code> | ||
| 28 | * | ||
| 29 | * Set <code>remove</code> to true if you want the filter to be removed when the tween completes. <br /><br /> | ||
| 30 | * | ||
| 31 | * <b>USAGE:</b><br /><br /> | ||
| 32 | * <code> | ||
| 33 | * import com.greensock.TweenLite; <br /> | ||
| 34 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 35 | * import com.greensock.plugins.GlowFilterPlugin; <br /> | ||
| 36 | * TweenPlugin.activate([GlowFilterPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 37 | * | ||
| 38 | * TweenLite.to(mc, 1, {glowFilter:{color:0x00FF00, blurX:10, blurY:10, strength:1, alpha:1}});<br /><br /> | ||
| 39 | * </code> | ||
| 40 | * | ||
| 41 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 42 | * | ||
| 43 | * @author Jack Doyle, jack@greensock.com | ||
| 44 | */ | ||
| 45 | public class GlowFilterPlugin extends FilterPlugin { | ||
| 46 | /** @private **/ | ||
| 47 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 48 | /** @private **/ | ||
| 49 | private static var _propNames:Array = ["color","alpha","blurX","blurY","strength","quality","inner","knockout"]; | ||
| 50 | |||
| 51 | /** @private **/ | ||
| 52 | public function GlowFilterPlugin() { | ||
| 53 | super(); | ||
| 54 | this.propName = "glowFilter"; | ||
| 55 | this.overwriteProps = ["glowFilter"]; | ||
| 56 | } | ||
| 57 | |||
| 58 | /** @private **/ | ||
| 59 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 60 | _target = target; | ||
| 61 | _type = GlowFilter; | ||
| 62 | initFilter(value, new GlowFilter(0xFFFFFF, 0, 0, 0, value.strength || 1, value.quality || 2, value.inner, value.knockout), _propNames); | ||
| 63 | return true; | ||
| 64 | } | ||
| 65 | |||
| 66 | } | ||
| 67 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.03 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import com.greensock.*; | ||
| 10 | /** | ||
| 11 | * Although hex colors are technically numbers, if you try to tween them conventionally, | ||
| 12 | * you'll notice that they don't tween smoothly. To tween them properly, the red, green, and | ||
| 13 | * blue components must be extracted and tweened independently. The HexColorsPlugin makes it easy. | ||
| 14 | * To tween a property of your object that's a hex color to another hex color, just pass a hexColors | ||
| 15 | * Object with properties named the same as your object's hex color properties. For example, | ||
| 16 | * if myObject has a "myHexColor" property that you'd like to tween to red (<code>0xFF0000</code>) over the | ||
| 17 | * course of 2 seconds, you'd do:<br /><br /><code> | ||
| 18 | * | ||
| 19 | * TweenMax.to(myObject, 2, {hexColors:{myHexColor:0xFF0000}});<br /><br /></code> | ||
| 20 | * | ||
| 21 | * You can pass in any number of hexColor properties. <br /><br /> | ||
| 22 | * | ||
| 23 | * <b>USAGE:</b><br /><br /> | ||
| 24 | * <code> | ||
| 25 | * import com.greensock.TweenLite; <br /> | ||
| 26 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 27 | * import com.greensock.plugins.HexColorsPlugin; <br /> | ||
| 28 | * TweenPlugin.activate([HexColorsPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 29 | * | ||
| 30 | * TweenLite.to(myObject, 2, {hexColors:{myHexColor:0xFF0000}}); <br /><br /></code> | ||
| 31 | * | ||
| 32 | * Or if you just want to tween a color and apply it somewhere on every frame, you could do:<br /><br /><code> | ||
| 33 | * | ||
| 34 | * var myColor:Object = {hex:0xFF0000};<br /> | ||
| 35 | * TweenLite.to(myColor, 2, {hexColors:{hex:0x0000FF}, onUpdate:applyColor});<br /> | ||
| 36 | * function applyColor():void {<br /> | ||
| 37 | * mc.graphics.clear();<br /> | ||
| 38 | * mc.graphics.beginFill(myColor.hex, 1);<br /> | ||
| 39 | * mc.graphics.drawRect(0, 0, 100, 100);<br /> | ||
| 40 | * mc.graphics.endFill();<br /> | ||
| 41 | * }<br /><br /> | ||
| 42 | * </code> | ||
| 43 | * | ||
| 44 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 45 | * | ||
| 46 | * @author Jack Doyle, jack@greensock.com | ||
| 47 | */ | ||
| 48 | public class HexColorsPlugin extends TweenPlugin { | ||
| 49 | /** @private **/ | ||
| 50 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 51 | |||
| 52 | /** @private **/ | ||
| 53 | protected var _colors:Array; | ||
| 54 | |||
| 55 | /** @private **/ | ||
| 56 | public function HexColorsPlugin() { | ||
| 57 | super(); | ||
| 58 | this.propName = "hexColors"; | ||
| 59 | this.overwriteProps = []; | ||
| 60 | _colors = []; | ||
| 61 | } | ||
| 62 | |||
| 63 | /** @private **/ | ||
| 64 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 65 | for (var p:String in value) { | ||
| 66 | initColor(target, p, uint(target[p]), uint(value[p])); | ||
| 67 | } | ||
| 68 | return true; | ||
| 69 | } | ||
| 70 | |||
| 71 | /** @private **/ | ||
| 72 | public function initColor(target:Object, propName:String, start:uint, end:uint):void { | ||
| 73 | if (start != end) { | ||
| 74 | var r:Number = start >> 16; | ||
| 75 | var g:Number = (start >> 8) & 0xff; | ||
| 76 | var b:Number = start & 0xff; | ||
| 77 | _colors[_colors.length] = [target, | ||
| 78 | propName, | ||
| 79 | r, | ||
| 80 | (end >> 16) - r, | ||
| 81 | g, | ||
| 82 | ((end >> 8) & 0xff) - g, | ||
| 83 | b, | ||
| 84 | (end & 0xff) - b]; | ||
| 85 | this.overwriteProps[this.overwriteProps.length] = propName; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | /** @private **/ | ||
| 90 | override public function killProps(lookup:Object):void { | ||
| 91 | for (var i:int = _colors.length - 1; i > -1; i--) { | ||
| 92 | if (lookup[_colors[i][1]] != undefined) { | ||
| 93 | _colors.splice(i, 1); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | super.killProps(lookup); | ||
| 97 | } | ||
| 98 | |||
| 99 | /** @private **/ | ||
| 100 | override public function set changeFactor(n:Number):void { | ||
| 101 | var i:int, a:Array; | ||
| 102 | for (i = _colors.length - 1; i > -1; i--) { | ||
| 103 | a = _colors[i]; | ||
| 104 | a[0][a[1]] = ((a[2] + (n * a[3])) << 16 | (a[4] + (n * a[5])) << 8 | (a[6] + (n * a[7]))); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 109 | } | ||
| 110 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.02 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | /** | ||
| 10 | * Performs SLERP interpolation between 2 Quaternions. Each Quaternion should have x, y, z, and w properties. | ||
| 11 | * Simply pass in an Object containing properties that correspond to your object's quaternion properties. | ||
| 12 | * For example, if your myCamera3D has an "orientation" property that's a Quaternion and you want to | ||
| 13 | * tween its values to x:1, y:0.5, z:0.25, w:0.5, you could do:<br /><br /><code> | ||
| 14 | * | ||
| 15 | * TweenLite.to(myCamera3D, 2, {quaternions:{orientation:new Quaternion(1, 0.5, 0.25, 0.5)}});<br /><br /></code> | ||
| 16 | * | ||
| 17 | * You can define as many quaternion properties as you want.<br /><br /> | ||
| 18 | * | ||
| 19 | * <b>USAGE:</b><br /><br /> | ||
| 20 | * <code> | ||
| 21 | * import com.greensock.TweenLite; <br /> | ||
| 22 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 23 | * import com.greensock.plugins.QuaternionsPlugin; <br /> | ||
| 24 | * TweenPlugin.activate([QuaternionsPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 25 | * | ||
| 26 | * TweenLite.to(myCamera3D, 2, {quaternions:{orientation:new Quaternion(1, 0.5, 0.25, 0.5)}}); <br /><br /> | ||
| 27 | * </code> | ||
| 28 | * | ||
| 29 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 30 | * | ||
| 31 | * @author Jack Doyle, jack@greensock.com | ||
| 32 | */ | ||
| 33 | public class QuaternionsPlugin extends TweenPlugin { | ||
| 34 | /** @private **/ | ||
| 35 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 36 | |||
| 37 | /** @private **/ | ||
| 38 | protected static const _RAD2DEG:Number = 180 / Math.PI; //precalculate for speed | ||
| 39 | |||
| 40 | /** @private **/ | ||
| 41 | protected var _target:Object; | ||
| 42 | /** @private **/ | ||
| 43 | protected var _quaternions:Array = []; | ||
| 44 | |||
| 45 | /** @private **/ | ||
| 46 | public function QuaternionsPlugin() { | ||
| 47 | super(); | ||
| 48 | this.propName = "quaternions"; //name of the special property that the plugin should intercept/manage | ||
| 49 | this.overwriteProps = []; | ||
| 50 | } | ||
| 51 | |||
| 52 | /** @private **/ | ||
| 53 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 54 | if (value == null) { | ||
| 55 | return false; | ||
| 56 | } | ||
| 57 | for (var p:String in value) { | ||
| 58 | initQuaternion(target[p], value[p], p); | ||
| 59 | } | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | /** @private **/ | ||
| 64 | public function initQuaternion(start:Object, end:Object, propName:String):void { | ||
| 65 | var angle:Number, q1:Object, q2:Object, x1:Number, x2:Number, y1:Number, y2:Number, z1:Number, z2:Number, w1:Number, w2:Number, theta:Number; | ||
| 66 | q1 = start; | ||
| 67 | q2 = end; | ||
| 68 | x1 = q1.x; x2 = q2.x; | ||
| 69 | y1 = q1.y; y2 = q2.y; | ||
| 70 | z1 = q1.z; z2 = q2.z; | ||
| 71 | w1 = q1.w; w2 = q2.w; | ||
| 72 | angle = x1 * x2 + y1 * y2 + z1 * z2 + w1 * w2; | ||
| 73 | if (angle < 0) { | ||
| 74 | x1 *= -1; | ||
| 75 | y1 *= -1; | ||
| 76 | z1 *= -1; | ||
| 77 | w1 *= -1; | ||
| 78 | angle *= -1; | ||
| 79 | } | ||
| 80 | if ((angle + 1) < 0.000001) { | ||
| 81 | y2 = -y1; | ||
| 82 | x2 = x1; | ||
| 83 | w2 = -w1; | ||
| 84 | z2 = z1; | ||
| 85 | } | ||
| 86 | theta = Math.acos(angle); | ||
| 87 | _quaternions[_quaternions.length] = [q1, propName, x1, x2, y1, y2, z1, z2, w1, w2, angle, theta, 1 / Math.sin(theta)]; | ||
| 88 | this.overwriteProps[this.overwriteProps.length] = propName; | ||
| 89 | } | ||
| 90 | |||
| 91 | /** @private **/ | ||
| 92 | override public function killProps(lookup:Object):void { | ||
| 93 | for (var i:int = _quaternions.length - 1; i > -1; i--) { | ||
| 94 | if (lookup[_quaternions[i][1]] != undefined) { | ||
| 95 | _quaternions.splice(i, 1); | ||
| 96 | } | ||
| 97 | } | ||
| 98 | super.killProps(lookup); | ||
| 99 | } | ||
| 100 | |||
| 101 | /** @private **/ | ||
| 102 | override public function set changeFactor(n:Number):void { | ||
| 103 | var i:int, q:Array, scale:Number, invScale:Number; | ||
| 104 | for (i = _quaternions.length - 1; i > -1; i--) { | ||
| 105 | q = _quaternions[i]; | ||
| 106 | if ((q[10] + 1) > 0.000001) { | ||
| 107 | if ((1 - q[10]) >= 0.000001) { | ||
| 108 | scale = Math.sin(q[11] * (1 - n)) * q[12]; | ||
| 109 | invScale = Math.sin(q[11] * n) * q[12]; | ||
| 110 | } else { | ||
| 111 | scale = 1 - n; | ||
| 112 | invScale = n; | ||
| 113 | } | ||
| 114 | } else { | ||
| 115 | scale = Math.sin(Math.PI * (0.5 - n)); | ||
| 116 | invScale = Math.sin(Math.PI * n); | ||
| 117 | } | ||
| 118 | q[0].x = scale * q[2] + invScale * q[3]; | ||
| 119 | q[0].y = scale * q[4] + invScale * q[5]; | ||
| 120 | q[0].z = scale * q[6] + invScale * q[7]; | ||
| 121 | q[0].w = scale * q[8] + invScale * q[9]; | ||
| 122 | } | ||
| 123 | /* | ||
| 124 | Array access is faster (though less readable). Here is the key: | ||
| 125 | 0 - target | ||
| 126 | 1 = propName | ||
| 127 | 2 = x1 | ||
| 128 | 3 = x2 | ||
| 129 | 4 = y1 | ||
| 130 | 5 = y2 | ||
| 131 | 6 = z1 | ||
| 132 | 7 = z2 | ||
| 133 | 8 = w1 | ||
| 134 | 9 = w2 | ||
| 135 | 10 = angle | ||
| 136 | 11 = theta | ||
| 137 | 12 = invTheta | ||
| 138 | */ | ||
| 139 | } | ||
| 140 | |||
| 141 | |||
| 142 | } | ||
| 143 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.03 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import flash.geom.ColorTransform; | ||
| 10 | import com.greensock.*; | ||
| 11 | import com.greensock.plugins.*; | ||
| 12 | /** | ||
| 13 | * Removes the tint of a DisplayObject over time. <br /><br /> | ||
| 14 | * | ||
| 15 | * <b>USAGE:</b><br /><br /> | ||
| 16 | * <code> | ||
| 17 | * import com.greensock.TweenLite; <br /> | ||
| 18 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 19 | * import com.greensock.plugins.RemoveTintPlugin; <br /> | ||
| 20 | * TweenPlugin.activate([RemoveTintPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 21 | * | ||
| 22 | * TweenLite.to(mc, 1, {removeTint:true}); <br /><br /> | ||
| 23 | * </code> | ||
| 24 | * | ||
| 25 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 26 | * | ||
| 27 | * @author Jack Doyle, jack@greensock.com | ||
| 28 | */ | ||
| 29 | public class RemoveTintPlugin extends TintPlugin { | ||
| 30 | /** @private **/ | ||
| 31 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 32 | |||
| 33 | /** @private **/ | ||
| 34 | public function RemoveTintPlugin() { | ||
| 35 | super(); | ||
| 36 | this.propName = "removeTint"; | ||
| 37 | } | ||
| 38 | |||
| 39 | } | ||
| 40 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.02 | ||
| 3 | * DATE: 7/15/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import com.greensock.*; | ||
| 10 | /** | ||
| 11 | * If you'd like the inbetween values in a tween to always get rounded to the nearest integer, use the roundProps | ||
| 12 | * special property. Just pass in an Array containing the property names that you'd like rounded. For example, | ||
| 13 | * if you're tweening the x, y, and alpha properties of mc and you want to round the x and y values (not alpha) | ||
| 14 | * every time the tween is rendered, you'd do: <br /><br /><code> | ||
| 15 | * | ||
| 16 | * TweenMax.to(mc, 2, {x:300, y:200, alpha:0.5, roundProps:["x","y"]});<br /><br /></code> | ||
| 17 | * | ||
| 18 | * <b>IMPORTANT:</b> roundProps requires TweenMax! TweenLite tweens will not round properties. <br /><br /> | ||
| 19 | * | ||
| 20 | * <b>USAGE:</b><br /><br /> | ||
| 21 | * <code> | ||
| 22 | * import com.greensock.TweenMax; <br /><br /> | ||
| 23 | * | ||
| 24 | * TweenMax.to(mc, 2, {x:300, y:200, alpha:0.5, roundProps:["x","y"]}); <br /><br /> | ||
| 25 | * </code> | ||
| 26 | * | ||
| 27 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 28 | * | ||
| 29 | * @author Jack Doyle, jack@greensock.com | ||
| 30 | */ | ||
| 31 | public class RoundPropsPlugin extends TweenPlugin { | ||
| 32 | /** @private **/ | ||
| 33 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 34 | |||
| 35 | /** @private **/ | ||
| 36 | public function RoundPropsPlugin() { | ||
| 37 | super(); | ||
| 38 | this.propName = "roundProps"; | ||
| 39 | this.overwriteProps = []; | ||
| 40 | this.round = true; | ||
| 41 | } | ||
| 42 | |||
| 43 | /** @private **/ | ||
| 44 | public function add(object:Object, propName:String, start:Number, change:Number):void { | ||
| 45 | addTween(object, propName, start, start + change, propName); | ||
| 46 | this.overwriteProps[this.overwriteProps.length] = propName; | ||
| 47 | } | ||
| 48 | |||
| 49 | } | ||
| 50 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.13 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.*; | ||
| 11 | /** | ||
| 12 | * ScalePlugin combines scaleX and scaleY into one "scale" property. <br /><br /> | ||
| 13 | * | ||
| 14 | * <b>USAGE:</b><br /><br /> | ||
| 15 | * <code> | ||
| 16 | * import com.greensock.TweenLite; <br /> | ||
| 17 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 18 | * import com.greensock.plugins.ScalePlugin; <br /> | ||
| 19 | * TweenPlugin.activate([ScalePlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 20 | * | ||
| 21 | * TweenLite.to(mc, 1, {scale:2}); //tweens horizontal and vertical scale simultaneously <br /><br /> | ||
| 22 | * </code> | ||
| 23 | * | ||
| 24 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 25 | * | ||
| 26 | * @author Jack Doyle, jack@greensock.com | ||
| 27 | */ | ||
| 28 | public class ScalePlugin extends TweenPlugin { | ||
| 29 | /** @private **/ | ||
| 30 | public static const API:Number = 1.0; | ||
| 31 | |||
| 32 | /** @private **/ | ||
| 33 | protected var _target:Object; | ||
| 34 | /** @private **/ | ||
| 35 | protected var _startX:Number; | ||
| 36 | /** @private **/ | ||
| 37 | protected var _changeX:Number; | ||
| 38 | /** @private **/ | ||
| 39 | protected var _startY:Number; | ||
| 40 | /** @private **/ | ||
| 41 | protected var _changeY:Number; | ||
| 42 | |||
| 43 | /** @private **/ | ||
| 44 | public function ScalePlugin() { | ||
| 45 | super(); | ||
| 46 | this.propName = "scale"; | ||
| 47 | this.overwriteProps = ["scaleX", "scaleY", "width", "height"]; | ||
| 48 | } | ||
| 49 | |||
| 50 | /** @private **/ | ||
| 51 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 52 | if (!target.hasOwnProperty("scaleX")) { | ||
| 53 | return false; | ||
| 54 | } | ||
| 55 | _target = target; | ||
| 56 | _startX = _target.scaleX; | ||
| 57 | _startY = _target.scaleY; | ||
| 58 | if (typeof(value) == "number") { | ||
| 59 | _changeX = value - _startX; | ||
| 60 | _changeY = value - _startY; | ||
| 61 | } else { | ||
| 62 | _changeX = _changeY = Number(value); | ||
| 63 | } | ||
| 64 | return true; | ||
| 65 | } | ||
| 66 | |||
| 67 | /** @private **/ | ||
| 68 | override public function killProps(lookup:Object):void { | ||
| 69 | var i:int = this.overwriteProps.length; | ||
| 70 | while (i--) { | ||
| 71 | if (this.overwriteProps[i] in lookup) { //if any of the properties are found in the lookup, this whole plugin instance should be essentially deactivated. To do that, we must empty the overwriteProps Array. | ||
| 72 | this.overwriteProps = []; | ||
| 73 | return; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | /** @private **/ | ||
| 79 | override public function set changeFactor(n:Number):void { | ||
| 80 | _target.scaleX = _startX + (n * _changeX); | ||
| 81 | _target.scaleY = _startY + (n * _changeY); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.02 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import flash.geom.Rectangle; | ||
| 10 | |||
| 11 | import com.greensock.*; | ||
| 12 | /** | ||
| 13 | * Tweens the scrollRect property of a DisplayObject. You can define any (or all) of the following | ||
| 14 | * properties: | ||
| 15 | * <code> | ||
| 16 | * <ul> | ||
| 17 | * <li> x : Number</li> | ||
| 18 | * <li> y : Number</li> | ||
| 19 | * <li> width : Number</li> | ||
| 20 | * <li> height : Number</li> | ||
| 21 | * <li> top : Number</li> | ||
| 22 | * <li> bottom : Number</li> | ||
| 23 | * <li> left : Number</li> | ||
| 24 | * <li> right : Number</li> | ||
| 25 | * </ul> | ||
| 26 | * </code><br /> | ||
| 27 | * | ||
| 28 | * <b>USAGE:</b><br /><br /> | ||
| 29 | * <code> | ||
| 30 | * import com.greensock.TweenLite; <br /> | ||
| 31 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 32 | * import com.greensock.plugins.ScrollRectPlugin; <br /> | ||
| 33 | * TweenPlugin.activate([ScrollRectPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 34 | * | ||
| 35 | * TweenLite.to(mc, 1, {scrollRect:{x:50, y:300, width:100, height:100}}); <br /><br /> | ||
| 36 | * </code> | ||
| 37 | * | ||
| 38 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 39 | * | ||
| 40 | * @author Jack Doyle, jack@greensock.com | ||
| 41 | */ | ||
| 42 | public class ScrollRectPlugin extends TweenPlugin { | ||
| 43 | /** @private **/ | ||
| 44 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 45 | |||
| 46 | /** @private **/ | ||
| 47 | protected var _target:DisplayObject; | ||
| 48 | /** @private **/ | ||
| 49 | protected var _rect:Rectangle; | ||
| 50 | |||
| 51 | /** @private **/ | ||
| 52 | public function ScrollRectPlugin() { | ||
| 53 | super(); | ||
| 54 | this.propName = "scrollRect"; | ||
| 55 | this.overwriteProps = ["scrollRect"]; | ||
| 56 | } | ||
| 57 | |||
| 58 | /** @private **/ | ||
| 59 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 60 | if (!(target is DisplayObject)) { | ||
| 61 | return false; | ||
| 62 | } | ||
| 63 | _target = target as DisplayObject; | ||
| 64 | if (_target.scrollRect != null) { | ||
| 65 | _rect = _target.scrollRect; | ||
| 66 | } else { | ||
| 67 | var r:Rectangle = _target.getBounds(_target); | ||
| 68 | _rect = new Rectangle(0, 0, r.width + r.x, r.height + r.y); | ||
| 69 | } | ||
| 70 | for (var p:String in value) { | ||
| 71 | addTween(_rect, p, _rect[p], value[p], p); | ||
| 72 | } | ||
| 73 | return true; | ||
| 74 | } | ||
| 75 | |||
| 76 | /** @private **/ | ||
| 77 | override public function set changeFactor(n:Number):void { | ||
| 78 | updateTweens(n); | ||
| 79 | _target.scrollRect = _rect; | ||
| 80 | } | ||
| 81 | |||
| 82 | } | ||
| 83 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.02 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import com.greensock.*; | ||
| 10 | /** | ||
| 11 | * Some components require resizing with setActualSize() instead of standard tweens of width/height in | ||
| 12 | * order to scale properly. The SetActualSizePlugin accommodates this easily. You can define the width, | ||
| 13 | * height, or both. <br /><br /> | ||
| 14 | * | ||
| 15 | * <b>USAGE:</b><br /><br /> | ||
| 16 | * <code> | ||
| 17 | * import com.greensock.TweenLite; <br /> | ||
| 18 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 19 | * import com.greensock.plugins.SetActualSizePlugin; <br /> | ||
| 20 | * TweenPlugin.activate([SetActualSizePlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 21 | * | ||
| 22 | * TweenLite.to(myComponent, 1, {setActualSize:{width:200, height:30}});<br /><br /> | ||
| 23 | * </code> | ||
| 24 | * | ||
| 25 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 26 | * | ||
| 27 | * @author Jack Doyle, jack@greensock.com | ||
| 28 | */ | ||
| 29 | public class SetActualSizePlugin extends TweenPlugin { | ||
| 30 | /** @private **/ | ||
| 31 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 32 | |||
| 33 | /** @private **/ | ||
| 34 | public var width:Number; | ||
| 35 | /** @private **/ | ||
| 36 | public var height:Number; | ||
| 37 | |||
| 38 | /** @private **/ | ||
| 39 | protected var _target:Object; | ||
| 40 | /** @private **/ | ||
| 41 | protected var _setWidth:Boolean; | ||
| 42 | /** @private **/ | ||
| 43 | protected var _setHeight:Boolean; | ||
| 44 | /** @private **/ | ||
| 45 | protected var _hasSetSize:Boolean; | ||
| 46 | |||
| 47 | /** @private **/ | ||
| 48 | public function SetActualSizePlugin() { | ||
| 49 | super(); | ||
| 50 | this.propName = "setActualSize"; | ||
| 51 | this.overwriteProps = ["setActualSize","setSize","width","height","scaleX","scaleY"]; | ||
| 52 | this.round = true; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** @private **/ | ||
| 56 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 57 | _target = target; | ||
| 58 | _hasSetSize = Boolean("setActualSize" in _target); | ||
| 59 | if ("width" in value && _target.width != value.width) { | ||
| 60 | addTween((_hasSetSize) ? this : _target, "width", _target.width, value.width, "width"); | ||
| 61 | _setWidth = _hasSetSize; | ||
| 62 | } | ||
| 63 | if ("height" in value && _target.height != value.height) { | ||
| 64 | addTween((_hasSetSize) ? this : _target, "height", _target.height, value.height, "height"); | ||
| 65 | _setHeight = _hasSetSize; | ||
| 66 | } | ||
| 67 | if (_tweens.length == 0) { //protects against occassions when the tween's start and end values are the same. In that case, the _tweens Array will be empty. | ||
| 68 | _hasSetSize = false; | ||
| 69 | } | ||
| 70 | return true; | ||
| 71 | } | ||
| 72 | |||
| 73 | /** @private **/ | ||
| 74 | override public function killProps(lookup:Object):void { | ||
| 75 | super.killProps(lookup); | ||
| 76 | if (_tweens.length == 0 || "setActualSize" in lookup) { | ||
| 77 | this.overwriteProps = []; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | /** @private **/ | ||
| 82 | override public function set changeFactor(n:Number):void { | ||
| 83 | updateTweens(n); | ||
| 84 | if (_hasSetSize) { | ||
| 85 | _target.setActualSize((_setWidth) ? this.width : _target.width, (_setHeight) ? this.height : _target.height); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | } | ||
| 91 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.04 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import com.greensock.*; | ||
| 10 | /** | ||
| 11 | * Some components require resizing with setSize() instead of standard tweens of width/height in | ||
| 12 | * order to scale properly. The SetSizePlugin accommodates this easily. You can define the width, | ||
| 13 | * height, or both. <br /><br /> | ||
| 14 | * | ||
| 15 | * <b>USAGE:</b><br /><br /> | ||
| 16 | * <code> | ||
| 17 | * import com.greensock.TweenLite; <br /> | ||
| 18 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 19 | * import com.greensock.plugins.SetSizePlugin; <br /> | ||
| 20 | * TweenPlugin.activate([SetSizePlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 21 | * | ||
| 22 | * TweenLite.to(myComponent, 1, {setSize:{width:200, height:30}}); <br /><br /> | ||
| 23 | * </code> | ||
| 24 | * | ||
| 25 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 26 | * | ||
| 27 | * @author Jack Doyle, jack@greensock.com | ||
| 28 | */ | ||
| 29 | public class SetSizePlugin extends TweenPlugin { | ||
| 30 | /** @private **/ | ||
| 31 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 32 | |||
| 33 | /** @private **/ | ||
| 34 | public var width:Number; | ||
| 35 | /** @private **/ | ||
| 36 | public var height:Number; | ||
| 37 | |||
| 38 | /** @private **/ | ||
| 39 | protected var _target:Object; | ||
| 40 | /** @private **/ | ||
| 41 | protected var _setWidth:Boolean; | ||
| 42 | /** @private **/ | ||
| 43 | protected var _setHeight:Boolean; | ||
| 44 | /** @private **/ | ||
| 45 | protected var _hasSetSize:Boolean; | ||
| 46 | |||
| 47 | /** @private **/ | ||
| 48 | public function SetSizePlugin() { | ||
| 49 | super(); | ||
| 50 | this.propName = "setSize"; | ||
| 51 | this.overwriteProps = ["setSize","setActualSize","width","height","scaleX","scaleY"]; | ||
| 52 | this.round = true; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** @private **/ | ||
| 56 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 57 | _target = target; | ||
| 58 | _hasSetSize = Boolean("setSize" in _target); | ||
| 59 | if ("width" in value && _target.width != value.width) { | ||
| 60 | addTween((_hasSetSize) ? this : _target, "width", _target.width, value.width, "width"); | ||
| 61 | _setWidth = _hasSetSize; | ||
| 62 | } | ||
| 63 | if ("height" in value && _target.height != value.height) { | ||
| 64 | addTween((_hasSetSize) ? this : _target, "height", _target.height, value.height, "height"); | ||
| 65 | _setHeight = _hasSetSize; | ||
| 66 | } | ||
| 67 | if (_tweens.length == 0) { | ||
| 68 | _hasSetSize = false; //protects from situations where the start and end values are the same, thus we're not really tweening anything. | ||
| 69 | } | ||
| 70 | return true; | ||
| 71 | } | ||
| 72 | |||
| 73 | /** @private **/ | ||
| 74 | override public function killProps(lookup:Object):void { | ||
| 75 | super.killProps(lookup); | ||
| 76 | if (_tweens.length == 0 || "setSize" in lookup) { | ||
| 77 | this.overwriteProps = []; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | /** @private **/ | ||
| 82 | override public function set changeFactor(n:Number):void { | ||
| 83 | updateTweens(n); | ||
| 84 | if (_hasSetSize) { | ||
| 85 | _target.setSize((_setWidth) ? this.width : _target.width, (_setHeight) ? this.height : _target.height); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | } | ||
| 90 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.2 | ||
| 3 | * DATE: 12/17/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import com.greensock.*; | ||
| 10 | /** | ||
| 11 | * To tween any rotation property of the target object in the shortest direction, use "shortRotation" | ||
| 12 | * For example, if <code>myObject.rotation</code> is currently 170 degrees and you want to tween it to -170 degrees, | ||
| 13 | * a normal rotation tween would travel a total of 340 degrees in the counter-clockwise direction, | ||
| 14 | * but if you use shortRotation, it would travel 20 degrees in the clockwise direction instead. You | ||
| 15 | * can define any number of rotation properties in the shortRotation object which makes 3D tweening | ||
| 16 | * easier, like:<br /><br /><code> | ||
| 17 | * | ||
| 18 | * TweenMax.to(mc, 2, {shortRotation:{rotationX:-170, rotationY:35, rotationZ:200}}); <br /><br /></code> | ||
| 19 | * | ||
| 20 | * <b>USAGE:</b><br /><br /> | ||
| 21 | * <code> | ||
| 22 | * import com.greensock.TweenLite; <br /> | ||
| 23 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 24 | * import com.greensock.plugins.ShortRotationPlugin; <br /> | ||
| 25 | * TweenPlugin.activate([ShortRotationPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 26 | * | ||
| 27 | * TweenLite.to(mc, 1, {shortRotation:{rotation:-170}});<br /><br /> | ||
| 28 | |||
| 29 | * //or for a 3D tween with multiple rotation values...<br /> | ||
| 30 | * TweenLite.to(mc, 1, {shortRotation:{rotationX:-170, rotationY:35, rotationZ:10}}); <br /><br /> | ||
| 31 | * </code> | ||
| 32 | * | ||
| 33 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 34 | * | ||
| 35 | * @author Jack Doyle, jack@greensock.com | ||
| 36 | */ | ||
| 37 | public class ShortRotationPlugin extends TweenPlugin { | ||
| 38 | /** @private **/ | ||
| 39 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 40 | |||
| 41 | /** @private **/ | ||
| 42 | public function ShortRotationPlugin() { | ||
| 43 | super(); | ||
| 44 | this.propName = "shortRotation"; | ||
| 45 | this.overwriteProps = []; | ||
| 46 | } | ||
| 47 | |||
| 48 | /** @private **/ | ||
| 49 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 50 | if (typeof(value) == "number") { | ||
| 51 | return false; | ||
| 52 | } | ||
| 53 | for (var p:String in value) { | ||
| 54 | initRotation(target, p, target[p], (typeof(value[p]) == "number") ? Number(value[p]) : target[p] + Number(value[p])); | ||
| 55 | } | ||
| 56 | return true; | ||
| 57 | } | ||
| 58 | |||
| 59 | /** @private **/ | ||
| 60 | public function initRotation(target:Object, propName:String, start:Number, end:Number):void { | ||
| 61 | var dif:Number = (end - start) % 360; | ||
| 62 | if (dif != dif % 180) { | ||
| 63 | dif = (dif < 0) ? dif + 360 : dif - 360; | ||
| 64 | } | ||
| 65 | addTween(target, propName, start, start + dif, propName); | ||
| 66 | this.overwriteProps[this.overwriteProps.length] = propName; | ||
| 67 | } | ||
| 68 | |||
| 69 | } | ||
| 70 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.0 | ||
| 3 | * DATE: 10/22/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.media.SoundTransform; | ||
| 11 | /** | ||
| 12 | * Tweens properties of an object's soundTransform property (like the volume, pan, leftToRight, etc. of a MovieClip/SoundChannel/NetStream). <br /><br /> | ||
| 13 | * | ||
| 14 | * <b>USAGE:</b><br /><br /> | ||
| 15 | * <code> | ||
| 16 | * import com.greensock.TweenLite; <br /> | ||
| 17 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 18 | * import com.greensock.plugins.SoundTransformPlugin; <br /> | ||
| 19 | * TweenPlugin.activate([SoundTransformPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 20 | * | ||
| 21 | * TweenLite.to(mc, 1, {soundTransform:{volume:0.2, pan:0.5}}); <br /><br /> | ||
| 22 | * </code> | ||
| 23 | * | ||
| 24 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 25 | * | ||
| 26 | * @author Jack Doyle, jack@greensock.com | ||
| 27 | */ | ||
| 28 | public class SoundTransformPlugin extends TweenPlugin { | ||
| 29 | /** @private **/ | ||
| 30 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 31 | |||
| 32 | /** @private **/ | ||
| 33 | protected var _target:Object; | ||
| 34 | /** @private **/ | ||
| 35 | protected var _st:SoundTransform; | ||
| 36 | |||
| 37 | /** @private **/ | ||
| 38 | public function SoundTransformPlugin() { | ||
| 39 | super(); | ||
| 40 | this.propName = "soundTransform"; | ||
| 41 | this.overwriteProps = ["soundTransform","volume"]; | ||
| 42 | } | ||
| 43 | |||
| 44 | /** @private **/ | ||
| 45 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 46 | if (!target.hasOwnProperty("soundTransform")) { | ||
| 47 | return false; | ||
| 48 | } | ||
| 49 | _target = target; | ||
| 50 | _st = _target.soundTransform; | ||
| 51 | for (var p:String in value) { | ||
| 52 | addTween(_st, p, _st[p], value[p], p); | ||
| 53 | } | ||
| 54 | return true; | ||
| 55 | } | ||
| 56 | |||
| 57 | /** @private **/ | ||
| 58 | override public function set changeFactor(n:Number):void { | ||
| 59 | updateTweens(n); | ||
| 60 | _target.soundTransform = _st; | ||
| 61 | } | ||
| 62 | |||
| 63 | } | ||
| 64 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.12 | ||
| 3 | * DATE: 10/2/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.display.*; | ||
| 9 | import flash.geom.ColorTransform; | ||
| 10 | import flash.geom.Transform; | ||
| 11 | |||
| 12 | import com.greensock.*; | ||
| 13 | import com.greensock.core.*; | ||
| 14 | /** | ||
| 15 | * To change a DisplayObject's tint/color, set this to the hex value of the tint you'd like | ||
| 16 | * to end up at (or begin at if you're using <code>TweenMax.from()</code>). An example hex value would be <code>0xFF0000</code>.<br /><br /> | ||
| 17 | * | ||
| 18 | * To remove a tint completely, use the RemoveTintPlugin (after activating it, you can just set <code>removeTint:true</code>) <br /><br /> | ||
| 19 | * | ||
| 20 | * <b>USAGE:</b><br /><br /> | ||
| 21 | * <code> | ||
| 22 | * import com.greensock.TweenLite; <br /> | ||
| 23 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 24 | * import com.greensock.plugins.TintPlugin; <br /> | ||
| 25 | * TweenPlugin.activate([TintPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 26 | * | ||
| 27 | * TweenLite.to(mc, 1, {tint:0xFF0000}); <br /><br /> | ||
| 28 | * </code> | ||
| 29 | * | ||
| 30 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 31 | * | ||
| 32 | * @author Jack Doyle, jack@greensock.com | ||
| 33 | */ | ||
| 34 | public class TintPlugin extends TweenPlugin { | ||
| 35 | /** @private **/ | ||
| 36 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 37 | /** @private **/ | ||
| 38 | protected static var _props:Array = ["redMultiplier", "greenMultiplier", "blueMultiplier", "alphaMultiplier", "redOffset", "greenOffset", "blueOffset", "alphaOffset"]; | ||
| 39 | |||
| 40 | /** @private **/ | ||
| 41 | protected var _transform:Transform; | ||
| 42 | /** @private **/ | ||
| 43 | protected var _ct:ColorTransform; | ||
| 44 | /** @private **/ | ||
| 45 | protected var _ignoreAlpha:Boolean; | ||
| 46 | |||
| 47 | /** @private **/ | ||
| 48 | public function TintPlugin() { | ||
| 49 | super(); | ||
| 50 | this.propName = "tint"; | ||
| 51 | this.overwriteProps = ["tint"]; | ||
| 52 | } | ||
| 53 | |||
| 54 | /** @private **/ | ||
| 55 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 56 | if (!(target is DisplayObject)) { | ||
| 57 | return false; | ||
| 58 | } | ||
| 59 | var end:ColorTransform = new ColorTransform(); | ||
| 60 | if (value != null && tween.vars.removeTint != true) { | ||
| 61 | end.color = uint(value); | ||
| 62 | } | ||
| 63 | _ignoreAlpha = true; | ||
| 64 | init(target as DisplayObject, end); | ||
| 65 | return true; | ||
| 66 | } | ||
| 67 | |||
| 68 | /** @private **/ | ||
| 69 | public function init(target:DisplayObject, end:ColorTransform):void { | ||
| 70 | _transform = target.transform; | ||
| 71 | _ct = _transform.colorTransform; | ||
| 72 | var i:int = _props.length; | ||
| 73 | var p:String; | ||
| 74 | while (i--) { | ||
| 75 | p = _props[i]; | ||
| 76 | if (_ct[p] != end[p]) { | ||
| 77 | _tweens[_tweens.length] = new PropTween(_ct, p, _ct[p], end[p] - _ct[p], "tint", false); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | /** @private **/ | ||
| 83 | override public function set changeFactor(n:Number):void { | ||
| 84 | updateTweens(n); | ||
| 85 | if (_ignoreAlpha) { | ||
| 86 | var ct:ColorTransform = _transform.colorTransform; | ||
| 87 | _ct.alphaMultiplier = ct.alphaMultiplier; | ||
| 88 | _ct.alphaOffset = ct.alphaOffset; | ||
| 89 | } | ||
| 90 | _transform.colorTransform = _ct; | ||
| 91 | } | ||
| 92 | |||
| 93 | } | ||
| 94 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 0.96 | ||
| 3 | * DATE: 1/9/2010 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.*; | ||
| 11 | import flash.geom.Matrix; | ||
| 12 | import flash.geom.Transform; | ||
| 13 | /** | ||
| 14 | * TransformMatrixPlugin allows you to tween a DisplayObject's transform.matrix values directly | ||
| 15 | * (<code>a, b, c, d, tx, and ty</code>) or use common properties like <code>x, y, scaleX, scaleY, skewX, skewY,</code> and <code>rotation</code>. | ||
| 16 | * To skew without adjusting scale visually, use skewX2 and skewY2 instead of skewX and skewY. | ||
| 17 | * <br /><br /> | ||
| 18 | * | ||
| 19 | * <b>USAGE:</b><br /><br /> | ||
| 20 | * <code> | ||
| 21 | * import com.greensock.TweenLite; <br /> | ||
| 22 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 23 | * import com.greensock.plugins.TransformMatrixPlugin; <br /> | ||
| 24 | * TweenPlugin.activate([TransformMatrixPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 25 | * | ||
| 26 | * TweenLite.to(mc, 1, {transformMatrix:{x:50, y:300, scaleX:2, scaleY:2}}); <br /><br /> | ||
| 27 | * | ||
| 28 | * //-OR-<br /><br /> | ||
| 29 | * | ||
| 30 | * TweenLite.to(mc, 1, {transformMatrix:{tx:50, ty:300, a:2, d:2}}); <br /><br /> | ||
| 31 | * | ||
| 32 | * </code> | ||
| 33 | * | ||
| 34 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 35 | * | ||
| 36 | * @author Jack Doyle, jack@greensock.com | ||
| 37 | */ | ||
| 38 | public class TransformMatrixPlugin extends TweenPlugin { | ||
| 39 | /** @private **/ | ||
| 40 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 41 | /** @private **/ | ||
| 42 | private static const _DEG2RAD:Number = Math.PI / 180; | ||
| 43 | /** @private **/ | ||
| 44 | private static const _RAD2DEG:Number = 180 / Math.PI; | ||
| 45 | |||
| 46 | /** @private **/ | ||
| 47 | protected var _transform:Transform; | ||
| 48 | /** @private **/ | ||
| 49 | protected var _matrix:Matrix; | ||
| 50 | /** @private **/ | ||
| 51 | protected var _txStart:Number; | ||
| 52 | /** @private **/ | ||
| 53 | protected var _txChange:Number; | ||
| 54 | /** @private **/ | ||
| 55 | protected var _tyStart:Number; | ||
| 56 | /** @private **/ | ||
| 57 | protected var _tyChange:Number; | ||
| 58 | /** @private **/ | ||
| 59 | protected var _aStart:Number; | ||
| 60 | /** @private **/ | ||
| 61 | protected var _aChange:Number; | ||
| 62 | /** @private **/ | ||
| 63 | protected var _bStart:Number; | ||
| 64 | /** @private **/ | ||
| 65 | protected var _bChange:Number; | ||
| 66 | /** @private **/ | ||
| 67 | protected var _cStart:Number; | ||
| 68 | /** @private **/ | ||
| 69 | protected var _cChange:Number; | ||
| 70 | /** @private **/ | ||
| 71 | protected var _dStart:Number; | ||
| 72 | /** @private **/ | ||
| 73 | protected var _dChange:Number; | ||
| 74 | /** @private **/ | ||
| 75 | protected var _angleChange:Number = 0; | ||
| 76 | |||
| 77 | /** @private **/ | ||
| 78 | public function TransformMatrixPlugin() { | ||
| 79 | super(); | ||
| 80 | this.propName = "transformMatrix"; | ||
| 81 | this.overwriteProps = ["x","y","scaleX","scaleY","rotation","transformMatrix","transformAroundPoint","transformAroundCenter"]; | ||
| 82 | } | ||
| 83 | |||
| 84 | /** @private **/ | ||
| 85 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 86 | _transform = target.transform as Transform; | ||
| 87 | _matrix = _transform.matrix; | ||
| 88 | var matrix:Matrix = _matrix.clone(); | ||
| 89 | _txStart = matrix.tx; | ||
| 90 | _tyStart = matrix.ty; | ||
| 91 | _aStart = matrix.a; | ||
| 92 | _bStart = matrix.b; | ||
| 93 | _cStart = matrix.c; | ||
| 94 | _dStart = matrix.d; | ||
| 95 | |||
| 96 | if ("x" in value) { | ||
| 97 | _txChange = (typeof(value.x) == "number") ? value.x - _txStart : Number(value.x); | ||
| 98 | } else if ("tx" in value) { | ||
| 99 | _txChange = value.tx - _txStart; | ||
| 100 | } else { | ||
| 101 | _txChange = 0; | ||
| 102 | } | ||
| 103 | if ("y" in value) { | ||
| 104 | _tyChange = (typeof(value.y) == "number") ? value.y - _tyStart : Number(value.y); | ||
| 105 | } else if ("ty" in value) { | ||
| 106 | _tyChange = value.ty - _tyStart; | ||
| 107 | } else { | ||
| 108 | _tyChange = 0; | ||
| 109 | } | ||
| 110 | _aChange = ("a" in value) ? value.a - _aStart : 0; | ||
| 111 | _bChange = ("b" in value) ? value.b - _bStart : 0; | ||
| 112 | _cChange = ("c" in value) ? value.c - _cStart : 0; | ||
| 113 | _dChange = ("d" in value) ? value.d - _dStart : 0; | ||
| 114 | |||
| 115 | if (("rotation" in value) || ("scale" in value) || ("scaleX" in value) || ("scaleY" in value) || ("skewX" in value) || ("skewY" in value) || ("skewX2" in value) || ("skewY2" in value)) { | ||
| 116 | var ratioX:Number, ratioY:Number; | ||
| 117 | var scaleX:Number = Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b); //Bugs in the Flex framework prevent DisplayObject.scaleX from working consistently, so we must determine it using the matrix. | ||
| 118 | if (matrix.a < 0 && matrix.d > 0) { | ||
| 119 | scaleX = -scaleX; | ||
| 120 | } | ||
| 121 | var scaleY:Number = Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d); //Bugs in the Flex framework prevent DisplayObject.scaleY from working consistently, so we must determine it using the matrix. | ||
| 122 | if (matrix.d < 0 && matrix.a > 0) { | ||
| 123 | scaleY = -scaleY; | ||
| 124 | } | ||
| 125 | var angle:Number = Math.atan2(matrix.b, matrix.a); //Bugs in the Flex framework prevent DisplayObject.rotation from working consistently, so we must determine it using the matrix | ||
| 126 | if (matrix.a < 0 && matrix.d >= 0) { | ||
| 127 | angle += (angle <= 0) ? Math.PI : -Math.PI; | ||
| 128 | } | ||
| 129 | var skewX:Number = Math.atan2(-_matrix.c, _matrix.d) - angle; | ||
| 130 | |||
| 131 | var finalAngle:Number = ("rotation" in value) ? (typeof(value.rotation) == "number") ? value.rotation * _DEG2RAD : Number(value.rotation) * _DEG2RAD + angle : angle; | ||
| 132 | var finalSkewX:Number = ("skewX" in value) ? (typeof(value.skewX) == "number") ? Number(value.skewX) * _DEG2RAD : Number(value.skewX) * _DEG2RAD + skewX : 0; | ||
| 133 | |||
| 134 | if ("skewY" in value) { //skewY is just a combonation of rotation and skewX | ||
| 135 | var skewY:Number = (typeof(value.skewY) == "number") ? value.skewY * _DEG2RAD : Number(value.skewY) * _DEG2RAD - skewX; | ||
| 136 | finalAngle += skewY + skewX; | ||
| 137 | finalSkewX -= skewY; | ||
| 138 | } | ||
| 139 | |||
| 140 | if (finalAngle != angle) { | ||
| 141 | if ("rotation" in value) { | ||
| 142 | _angleChange = finalAngle - angle; | ||
| 143 | finalAngle = angle; //to correctly affect the skewX calculations below | ||
| 144 | } else { | ||
| 145 | matrix.rotate(finalAngle - angle); | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | if ("scale" in value) { | ||
| 150 | ratioX = Number(value.scale) / scaleX; | ||
| 151 | ratioY = Number(value.scale) / scaleY; | ||
| 152 | if (typeof(value.scale) != "number") { //relative value | ||
| 153 | ratioX += 1; | ||
| 154 | ratioY += 1; | ||
| 155 | } | ||
| 156 | } else { | ||
| 157 | if ("scaleX" in value) { | ||
| 158 | ratioX = Number(value.scaleX) / scaleX; | ||
| 159 | if (typeof(value.scaleX) != "number") { //relative value | ||
| 160 | ratioX += 1; | ||
| 161 | } | ||
| 162 | } | ||
| 163 | if ("scaleY" in value) { | ||
| 164 | ratioY = Number(value.scaleY) / scaleY; | ||
| 165 | if (typeof(value.scaleY) != "number") { //relative value | ||
| 166 | ratioY += 1; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | if (finalSkewX != skewX) { | ||
| 172 | matrix.c = -scaleY * Math.sin(finalSkewX + finalAngle); | ||
| 173 | matrix.d = scaleY * Math.cos(finalSkewX + finalAngle); | ||
| 174 | } | ||
| 175 | |||
| 176 | if ("skewX2" in value) { | ||
| 177 | if (typeof(value.skewX2) == "number") { | ||
| 178 | matrix.c = Math.tan(0 - (value.skewX2 * _DEG2RAD)); | ||
| 179 | } else { | ||
| 180 | matrix.c += Math.tan(0 - (Number(value.skewX2) * _DEG2RAD)); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | if ("skewY2" in value) { | ||
| 184 | if (typeof(value.skewY2) == "number") { | ||
| 185 | matrix.b = Math.tan(value.skewY2 * _DEG2RAD); | ||
| 186 | } else { | ||
| 187 | matrix.b += Math.tan(Number(value.skewY2) * _DEG2RAD); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | if (ratioX) { | ||
| 192 | matrix.a *= ratioX; | ||
| 193 | matrix.b *= ratioX; | ||
| 194 | } | ||
| 195 | if (ratioY) { | ||
| 196 | matrix.c *= ratioY; | ||
| 197 | matrix.d *= ratioY; | ||
| 198 | } | ||
| 199 | _aChange = matrix.a - _aStart; | ||
| 200 | _bChange = matrix.b - _bStart; | ||
| 201 | _cChange = matrix.c - _cStart; | ||
| 202 | _dChange = matrix.d - _dStart; | ||
| 203 | } | ||
| 204 | |||
| 205 | return true; | ||
| 206 | } | ||
| 207 | |||
| 208 | |||
| 209 | /** @private **/ | ||
| 210 | override public function set changeFactor(n:Number):void { | ||
| 211 | _matrix.a = _aStart + (n * _aChange); | ||
| 212 | _matrix.b = _bStart + (n * _bChange); | ||
| 213 | _matrix.c = _cStart + (n * _cChange); | ||
| 214 | _matrix.d = _dStart + (n * _dChange); | ||
| 215 | if (_angleChange) { | ||
| 216 | _matrix.rotate(_angleChange * n); | ||
| 217 | } | ||
| 218 | _matrix.tx = _txStart + (n * _txChange); | ||
| 219 | _matrix.ty = _tyStart + (n * _tyChange); | ||
| 220 | _transform.matrix = _matrix; | ||
| 221 | } | ||
| 222 | |||
| 223 | } | ||
| 224 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.31 | ||
| 3 | * DATE: 10/22/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | import com.greensock.core.*; | ||
| 10 | /** | ||
| 11 | * TweenPlugin is the base class for all TweenLite/TweenMax plugins. <br /><br /> | ||
| 12 | * | ||
| 13 | * <b>USAGE:</b><br /> | ||
| 14 | * | ||
| 15 | * To create your own plugin, extend TweenPlugin and override whichever methods you need. Typically, | ||
| 16 | * you only need to override onInitTween() and the changeFactor setter. I'd recommend looking at a | ||
| 17 | * simple plugin like FramePlugin or ScalePlugin and using it as a template of sorts. There are a few | ||
| 18 | * key concepts to keep in mind: | ||
| 19 | * <ol> | ||
| 20 | * <li> In the constructor, set this.propName to whatever special property you want your plugin to handle. </li> | ||
| 21 | * | ||
| 22 | * <li> When a tween that uses your plugin initializes its tween values (normally when it starts), a new instance | ||
| 23 | * of your plugin will be created and the onInitTween() method will be called. That's where you'll want to | ||
| 24 | * store any initial values and prepare for the tween. onInitTween() should return a Boolean value that | ||
| 25 | * essentially indicates whether or not the plugin initted successfully. If you return false, TweenLite/Max | ||
| 26 | * will just use a normal tween for the value, ignoring the plugin for that particular tween.</li> | ||
| 27 | * | ||
| 28 | * <li> The changeFactor setter will be updated on every frame during the course of the tween with a multiplier | ||
| 29 | * that describes the amount of change based on how far along the tween is and the ease applied. It will be | ||
| 30 | * zero at the beginning of the tween and 1 at the end, but inbetween it could be any value based on the | ||
| 31 | * ease applied (for example, an Elastic.easeOut tween would cause the value to shoot past 1 and back again before | ||
| 32 | * the end of the tween). So if the tween uses the Linear.easeNone easing equation, when it's halfway finished, | ||
| 33 | * the changeFactor will be 0.5. </li> | ||
| 34 | * | ||
| 35 | * <li> The overwriteProps is an Array that should contain the properties that your plugin should overwrite | ||
| 36 | * when OverwriteManager's mode is AUTO and a tween of the same object is created. For example, the | ||
| 37 | * autoAlpha plugin controls the "visible" and "alpha" properties of an object, so if another tween | ||
| 38 | * is created that controls the alpha of the target object, your plugin's killProps() will be called | ||
| 39 | * which should handle killing the "alpha" part of the tween. It is your responsibility to populate | ||
| 40 | * (and depopulate) the overwriteProps Array. Failure to do so properly can cause odd overwriting behavior.</li> | ||
| 41 | * | ||
| 42 | * <li> Note that there's a "round" property that indicates whether or not values in your plugin should be | ||
| 43 | * rounded to the nearest integer (compatible with TweenMax only). If you use the _tweens Array, populating | ||
| 44 | * it through the addTween() method, rounding will happen automatically (if necessary) in the | ||
| 45 | * updateTweens() method, but if you don't use addTween() and prefer to manually calculate tween values | ||
| 46 | * in your changeFactor setter, just remember to accommodate the "round" flag if it makes sense in your plugin.</li> | ||
| 47 | * | ||
| 48 | * <li> If you need to run a block of code when the tween has finished, point the onComplete property to a | ||
| 49 | * method you created inside your plugin.</li> | ||
| 50 | * | ||
| 51 | * <li> If you need to run a function when the tween gets disabled, point the onDisable property to a | ||
| 52 | * method you created inside your plugin. Same for onEnable if you need to run code when a tween is | ||
| 53 | * enabled. (A tween gets disabled when it gets overwritten or finishes or when its timeline gets disabled)</li> | ||
| 54 | * | ||
| 55 | * <li> Please use the same naming convention as the rest of the plugins, like MySpecialPropertyNamePlugin.</li> | ||
| 56 | * | ||
| 57 | * <li> IMPORTANT: The plugin framework is brand new, so there is a chance that it will change slightly over time and | ||
| 58 | * you may need to adjust your custom plugins if the framework changes. I'll try to minimize the changes, | ||
| 59 | * but I'd highly recommend getting a membership to Club GreenSock to make sure you get update notifications. | ||
| 60 | * See http://blog.greensock.com/club/ for details.</li> | ||
| 61 | * </ol> | ||
| 62 | * | ||
| 63 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 64 | * | ||
| 65 | * @author Jack Doyle, jack@greensock.com | ||
| 66 | */ | ||
| 67 | public class TweenPlugin { | ||
| 68 | public static const VERSION:Number = 1.31; | ||
| 69 | /** @private If the API/Framework for plugins changes in the future, this number helps determine compatibility **/ | ||
| 70 | public static const API:Number = 1.0; | ||
| 71 | |||
| 72 | /** @private Name of the special property that the plugin should intercept/handle **/ | ||
| 73 | public var propName:String; | ||
| 74 | |||
| 75 | /** | ||
| 76 | * @private | ||
| 77 | * Array containing the names of the properties that should be overwritten in OverwriteManager's | ||
| 78 | * AUTO mode. Typically the only value in this Array is the propName, but there are cases when it may | ||
| 79 | * be different. For example, a bezier tween's propName is "bezier" but it can manage many different properties | ||
| 80 | * like x, y, etc. depending on what's passed in to the tween. | ||
| 81 | */ | ||
| 82 | public var overwriteProps:Array; | ||
| 83 | |||
| 84 | /** @private If the values should be rounded to the nearest integer, set this to true. **/ | ||
| 85 | public var round:Boolean; | ||
| 86 | |||
| 87 | /** @private Priority level in the render queue **/ | ||
| 88 | public var priority:int = 0; | ||
| 89 | |||
| 90 | /** @private if the plugin actively changes properties of the target when it gets disabled (like the MotionBlurPlugin swaps out a temporary BitmapData for the target), activeDisplay should be true. Otherwise it should be false (it is much more common for it to be false). This is important because if it gets overwritten by another tween, that tween may init() with stale values - if activeDisable is true, it will force the new tween to re-init() when this plugin is overwritten (if ever). **/ | ||
| 91 | public var activeDisable:Boolean; | ||
| 92 | |||
| 93 | /** @private Called when the tween is complete. **/ | ||
| 94 | public var onComplete:Function; | ||
| 95 | |||
| 96 | /** @private Called when the tween gets re-enabled after having been initted. Like if it finishes and then gets restarted later. **/ | ||
| 97 | public var onEnable:Function; | ||
| 98 | |||
| 99 | /** @private Called either when the plugin gets overwritten or when its parent tween gets killed/disabled. **/ | ||
| 100 | public var onDisable:Function; | ||
| 101 | |||
| 102 | /** @private **/ | ||
| 103 | protected var _tweens:Array = []; | ||
| 104 | /** @private **/ | ||
| 105 | protected var _changeFactor:Number = 0; | ||
| 106 | |||
| 107 | |||
| 108 | public function TweenPlugin() { | ||
| 109 | //constructor | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * @private | ||
| 114 | * Gets called when any tween of the special property begins. Store any initial values | ||
| 115 | * and/or variables that will be used in the "changeFactor" setter when this method runs. | ||
| 116 | * | ||
| 117 | * @param target target object of the TweenLite instance using this plugin | ||
| 118 | * @param value The value that is passed in through the special property in the tween. | ||
| 119 | * @param tween The TweenLite or TweenMax instance using this plugin. | ||
| 120 | * @return If the initialization failed, it returns false. Otherwise true. It may fail if, for example, the plugin requires that the target be a DisplayObject or has some other unmet criteria in which case the plugin is skipped and a normal property tween is used inside TweenLite | ||
| 121 | */ | ||
| 122 | public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 123 | addTween(target, this.propName, target[this.propName], value, this.propName); | ||
| 124 | return true; | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | * @private | ||
| 129 | * Offers a simple way to add tweening values to the plugin. You don't need to use this, | ||
| 130 | * but it is convenient because the tweens get updated in the updateTweens() method which also | ||
| 131 | * handles rounding. killProps() nicely integrates with most tweens added via addTween() as well, | ||
| 132 | * but if you prefer to handle this manually in your plugin, you're welcome to. | ||
| 133 | * | ||
| 134 | * @param object target object whose property you'd like to tween. (i.e. myClip) | ||
| 135 | * @param propName the property name that should be tweened. (i.e. "x") | ||
| 136 | * @param start starting value | ||
| 137 | * @param end end value (can be either numeric or a string value. If it's a string, it will be interpreted as relative to the starting value) | ||
| 138 | * @param overwriteProp name of the property that should be associated with the tween for overwriting purposes. Normally, it's the same as propName, but not always. For example, you may tween the "changeFactor" property of a VisiblePlugin, but the property that it's actually controling in the end is "visible", so if a new overlapping tween of the target object is created that affects its "visible" property, this allows the plugin to kill the appropriate tween(s) when killProps() is called. | ||
| 139 | */ | ||
| 140 | protected function addTween(object:Object, propName:String, start:Number, end:*, overwriteProp:String=null):void { | ||
| 141 | if (end != null) { | ||
| 142 | var change:Number = (typeof(end) == "number") ? Number(end) - start : Number(end); | ||
| 143 | if (change != 0) { //don't tween values that aren't changing! It's a waste of CPU cycles | ||
| 144 | _tweens[_tweens.length] = new PropTween(object, propName, start, change, overwriteProp || propName, false); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | /** | ||
| 150 | * @private | ||
| 151 | * Updates all the tweens in the _tweens Array. | ||
| 152 | * | ||
| 153 | * @param changeFactor Multiplier describing the amount of change that should be applied. It will be zero at the beginning of the tween and 1 at the end, but inbetween it could be any value based on the ease applied (for example, an Elastic tween would cause the value to shoot past 1 and back again before the end of the tween) | ||
| 154 | */ | ||
| 155 | protected function updateTweens(changeFactor:Number):void { | ||
| 156 | var i:int = _tweens.length, pt:PropTween; | ||
| 157 | if (this.round) { | ||
| 158 | var val:Number; | ||
| 159 | while (i--) { | ||
| 160 | pt = _tweens[i]; | ||
| 161 | val = pt.start + (pt.change * changeFactor); | ||
| 162 | pt.target[pt.property] = (val > 0) ? int(val + 0.5) : int(val - 0.5); //4 times as fast as Math.round() | ||
| 163 | } | ||
| 164 | |||
| 165 | } else { | ||
| 166 | while (i--) { | ||
| 167 | pt = _tweens[i]; | ||
| 168 | pt.target[pt.property] = pt.start + (pt.change * changeFactor); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | /** | ||
| 174 | * @private | ||
| 175 | * In most cases, your custom updating code should go here. The changeFactor value describes the amount | ||
| 176 | * of change based on how far along the tween is and the ease applied. It will be zero at the beginning | ||
| 177 | * of the tween and 1 at the end, but inbetween it could be any value based on the ease applied (for example, | ||
| 178 | * an Elastic tween would cause the value to shoot past 1 and back again before the end of the tween) | ||
| 179 | * This value gets updated on every frame during the course of the tween. | ||
| 180 | * | ||
| 181 | * @param n Multiplier describing the amount of change that should be applied. It will be zero at the beginning of the tween and 1 at the end, but inbetween it could be any value based on the ease applied (for example, an Elastic tween would cause the value to shoot past 1 and back again before the end of the tween) | ||
| 182 | */ | ||
| 183 | public function set changeFactor(n:Number):void { | ||
| 184 | updateTweens(n); | ||
| 185 | _changeFactor = n; | ||
| 186 | } | ||
| 187 | |||
| 188 | public function get changeFactor():Number { | ||
| 189 | return _changeFactor; | ||
| 190 | } | ||
| 191 | |||
| 192 | /** | ||
| 193 | * @private | ||
| 194 | * Gets called on plugins that have multiple overwritable properties by OverwriteManager when | ||
| 195 | * in AUTO mode. Basically, it instructs the plugin to overwrite certain properties. For example, | ||
| 196 | * if a bezier tween is affecting x, y, and width, and then a new tween is created while the | ||
| 197 | * bezier tween is in progress, and the new tween affects the "x" property, we need a way | ||
| 198 | * to kill just the "x" part of the bezier tween. | ||
| 199 | * | ||
| 200 | * @param lookup An object containing properties that should be overwritten. We don't pass in an Array because looking up properties on the object is usually faster because it gives us random access. So to overwrite the "x" and "y" properties, a {x:true, y:true} object would be passed in. | ||
| 201 | */ | ||
| 202 | public function killProps(lookup:Object):void { | ||
| 203 | var i:int = this.overwriteProps.length; | ||
| 204 | while (i--) { | ||
| 205 | if (this.overwriteProps[i] in lookup) { | ||
| 206 | this.overwriteProps.splice(i, 1); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | i = _tweens.length; | ||
| 210 | while (i--) { | ||
| 211 | if (PropTween(_tweens[i]).name in lookup) { | ||
| 212 | _tweens.splice(i, 1); | ||
| 213 | } | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | /** | ||
| 218 | * @private | ||
| 219 | * This method is called inside TweenLite after significant events occur, like when a tween | ||
| 220 | * has finished initializing, when it has completed, and when its "enabled" property changes. | ||
| 221 | * For example, the MotionBlurPlugin must run after normal x/y/alpha PropTweens are rendered, | ||
| 222 | * so the "init" event reorders the PropTweens linked list in order of priority. Some plugins | ||
| 223 | * need to do things when a tween completes or when it gets disabled. Again, this | ||
| 224 | * method is only for internal use inside TweenLite. It is separated into | ||
| 225 | * this static method in order to minimize file size inside TweenLite. | ||
| 226 | * | ||
| 227 | * @param type The type of event "onInit", "onComplete", "onEnable", or "onDisable" | ||
| 228 | * @param tween The TweenLite/Max instance to which the event pertains | ||
| 229 | * @return A Boolean value indicating whether or not properties of the tween's target may have changed as a result of the event | ||
| 230 | */ | ||
| 231 | private static function onTweenEvent(type:String, tween:TweenLite):Boolean { | ||
| 232 | var pt:PropTween = tween.cachedPT1, changed:Boolean; | ||
| 233 | if (type == "onInit") { | ||
| 234 | //sorts the PropTween linked list in order of priority because some plugins need to render earlier/later than others, like MotionBlurPlugin applies its effects after all x/y/alpha tweens have rendered on each frame. | ||
| 235 | var tweens:Array = []; | ||
| 236 | while (pt) { | ||
| 237 | tweens[tweens.length] = pt; | ||
| 238 | pt = pt.nextNode; | ||
| 239 | } | ||
| 240 | tweens.sortOn("priority", Array.NUMERIC | Array.DESCENDING); | ||
| 241 | var i:int = tweens.length; | ||
| 242 | while (i--) { | ||
| 243 | PropTween(tweens[i]).nextNode = tweens[i + 1]; | ||
| 244 | PropTween(tweens[i]).prevNode = tweens[i - 1]; | ||
| 245 | } | ||
| 246 | tween.cachedPT1 = tweens[0]; | ||
| 247 | |||
| 248 | } else { | ||
| 249 | while (pt) { | ||
| 250 | if (pt.isPlugin && pt.target[type]) { | ||
| 251 | if (pt.target.activeDisable) { | ||
| 252 | changed = true; | ||
| 253 | } | ||
| 254 | pt.target[type](); | ||
| 255 | } | ||
| 256 | pt = pt.nextNode; | ||
| 257 | } | ||
| 258 | } | ||
| 259 | return changed; | ||
| 260 | } | ||
| 261 | |||
| 262 | /** | ||
| 263 | * @private | ||
| 264 | * Handles integrating the plugin into the GreenSock tweening platform. | ||
| 265 | * | ||
| 266 | * @param plugin An Array of Plugin classes (that all extend TweenPlugin) to be activated. For example, TweenPlugin.activate([FrameLabelPlugin, ShortRotationPlugin, TintPlugin]); | ||
| 267 | */ | ||
| 268 | public static function activate(plugins:Array):Boolean { | ||
| 269 | TweenLite.onPluginEvent = TweenPlugin.onTweenEvent; | ||
| 270 | var i:int = plugins.length, instance:Object; | ||
| 271 | while (i--) { | ||
| 272 | if (plugins[i].hasOwnProperty("API")) { | ||
| 273 | instance = new (plugins[i] as Class)(); | ||
| 274 | TweenLite.plugins[instance.propName] = plugins[i]; | ||
| 275 | } | ||
| 276 | } | ||
| 277 | return true; | ||
| 278 | } | ||
| 279 | |||
| 280 | } | ||
| 281 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 2.11 | ||
| 3 | * DATE: 11/14/2009 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.TweenMax.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import com.greensock.*; | ||
| 9 | |||
| 10 | import flash.display.*; | ||
| 11 | /** | ||
| 12 | * Toggles the visibility at the end of a tween. For example, if you want to set <code>visible</code> to false | ||
| 13 | * at the end of the tween, do:<br /><br /><code> | ||
| 14 | * | ||
| 15 | * TweenLite.to(mc, 1, {x:100, visible:false});<br /><br /></code> | ||
| 16 | * | ||
| 17 | * The <code>visible</code> property is forced to true during the course of the tween. <br /><br /> | ||
| 18 | * | ||
| 19 | * <b>USAGE:</b><br /><br /> | ||
| 20 | * <code> | ||
| 21 | * import com.greensock.TweenLite; <br /> | ||
| 22 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 23 | * import com.greensock.plugins.VisiblePlugin; <br /> | ||
| 24 | * TweenPlugin.activate([VisiblePlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 25 | * | ||
| 26 | * TweenLite.to(mc, 1, {x:100, visible:false}); <br /><br /> | ||
| 27 | * </code> | ||
| 28 | * | ||
| 29 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 30 | * | ||
| 31 | * @author Jack Doyle, jack@greensock.com | ||
| 32 | */ | ||
| 33 | public class VisiblePlugin extends TweenPlugin { | ||
| 34 | /** @private **/ | ||
| 35 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 36 | |||
| 37 | /** @private **/ | ||
| 38 | protected var _target:Object; | ||
| 39 | /** @private **/ | ||
| 40 | protected var _tween:TweenLite; | ||
| 41 | /** @private **/ | ||
| 42 | protected var _visible:Boolean; | ||
| 43 | /** @private **/ | ||
| 44 | protected var _initVal:Boolean; | ||
| 45 | |||
| 46 | /** @private **/ | ||
| 47 | public function VisiblePlugin() { | ||
| 48 | super(); | ||
| 49 | this.propName = "visible"; | ||
| 50 | this.overwriteProps = ["visible"]; | ||
| 51 | } | ||
| 52 | |||
| 53 | /** @private **/ | ||
| 54 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 55 | _target = target; | ||
| 56 | _tween = tween; | ||
| 57 | _initVal = _target.visible; | ||
| 58 | _visible = Boolean(value); | ||
| 59 | return true; | ||
| 60 | } | ||
| 61 | |||
| 62 | /** @private **/ | ||
| 63 | override public function set changeFactor(n:Number):void { | ||
| 64 | if (n == 1 && (_tween.cachedDuration == _tween.cachedTime || _tween.cachedTime == 0)) { //a changeFactor of 1 doesn't necessarily mean the tween is done - if the ease is Elastic.easeOut or Back.easeOut for example, they could hit 1 mid-tween. The reason we check to see if cachedTime is 0 is for from() tweens | ||
| 65 | _target.visible = _visible; | ||
| 66 | } else { | ||
| 67 | _target.visible = _initVal; //in case a completed tween is re-rendered at an earlier time. | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | } | ||
| 72 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * VERSION: 1.1 | ||
| 3 | * DATE: 2010-09-16 | ||
| 4 | * ACTIONSCRIPT VERSION: 3.0 | ||
| 5 | * UPDATES AND DOCUMENTATION AT: http://www.GreenSock.com | ||
| 6 | **/ | ||
| 7 | package com.greensock.plugins { | ||
| 8 | import flash.media.SoundTransform; | ||
| 9 | import com.greensock.*; | ||
| 10 | import com.greensock.plugins.*; | ||
| 11 | /** | ||
| 12 | * Tweens the volume of an object with a soundTransform property (MovieClip/SoundChannel/NetStream, etc.). <br /><br /> | ||
| 13 | * | ||
| 14 | * <b>USAGE:</b><br /><br /> | ||
| 15 | * <code> | ||
| 16 | * import com.greensock.TweenLite; <br /> | ||
| 17 | * import com.greensock.plugins.TweenPlugin; <br /> | ||
| 18 | * import com.greensock.plugins.VolumePlugin; <br /> | ||
| 19 | * TweenPlugin.activate([VolumePlugin]); //activation is permanent in the SWF, so this line only needs to be run once.<br /><br /> | ||
| 20 | * | ||
| 21 | * TweenLite.to(mc, 1, {volume:0}); <br /><br /> | ||
| 22 | * </code> | ||
| 23 | * | ||
| 24 | * <b>Copyright 2010, GreenSock. All rights reserved.</b> This work is subject to the terms in <a href="http://www.greensock.com/terms_of_use.html">http://www.greensock.com/terms_of_use.html</a> or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. | ||
| 25 | * | ||
| 26 | * @author Jack Doyle, jack@greensock.com | ||
| 27 | */ | ||
| 28 | public class VolumePlugin extends TweenPlugin { | ||
| 29 | /** @private **/ | ||
| 30 | public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility | ||
| 31 | |||
| 32 | /** @private **/ | ||
| 33 | protected var _target:Object; | ||
| 34 | /** @private **/ | ||
| 35 | protected var _st:SoundTransform; | ||
| 36 | |||
| 37 | /** @private **/ | ||
| 38 | public function VolumePlugin() { | ||
| 39 | super(); | ||
| 40 | this.propName = "volume"; | ||
| 41 | this.overwriteProps = ["volume"]; | ||
| 42 | } | ||
| 43 | |||
| 44 | /** @private **/ | ||
| 45 | override public function onInitTween(target:Object, value:*, tween:TweenLite):Boolean { | ||
| 46 | if (isNaN(value) || target.hasOwnProperty("volume") || !target.hasOwnProperty("soundTransform")) { | ||
| 47 | return false; | ||
| 48 | } | ||
| 49 | _target = target; | ||
| 50 | _st = _target.soundTransform; | ||
| 51 | addTween(_st, "volume", _st.volume, value, "volume"); | ||
| 52 | return true; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** @private **/ | ||
| 56 | override public function set changeFactor(n:Number):void { | ||
| 57 | updateTweens(n); | ||
| 58 | _target.soundTransform = _st; | ||
| 59 | } | ||
| 60 | |||
| 61 | } | ||
| 62 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
**HHS animation/source/index.fla
0 → 100644
No preview for this file type
**HHS animation/source/index.swf
0 → 100644
No preview for this file type
.gitignore
0 → 100644
| 1 | ### old Files ### | ||
| 2 | |||
| 3 | /08-** | ||
| 4 | /09-** | ||
| 5 | /10-** | ||
| 6 | /11-** | ||
| 7 | /12-** | ||
| 8 | /13-** | ||
| 9 | |||
| 10 | |||
| 11 | ### Wordpress ### | ||
| 12 | |||
| 13 | wp-config.php | ||
| 14 | |||
| 15 | |||
| 16 | ### Mac OSX ### | ||
| 17 | |||
| 18 | .DS_Store | ||
| 19 | Icon? | ||
| 20 | |||
| 21 | # Thumbnails | ||
| 22 | ._* | ||
| 23 | |||
| 24 | # Files that might appear on external disk | ||
| 25 | .Spotlight-V100 | ||
| 26 | .Trashes | ||
| 27 | |||
| 28 | |||
| 29 | ### PHPStorm ### | ||
| 30 | |||
| 31 | .idea/ | ||
| 32 | |||
| 33 | |||
| 34 | ### Eclipse ### | ||
| 35 | |||
| 36 | *.pydevproject | ||
| 37 | .project | ||
| 38 | .metadata | ||
| 39 | bin/** | ||
| 40 | tmp/** | ||
| 41 | tmp/**/* | ||
| 42 | *.tmp | ||
| 43 | *.bak | ||
| 44 | *.swp | ||
| 45 | *~.nib | ||
| 46 | local.properties | ||
| 47 | .classpath | ||
| 48 | .settings/ | ||
| 49 | .loadpath | ||
| 50 | |||
| 51 | # CDT-specific | ||
| 52 | .cproject | ||
| 53 | |||
| 54 | |||
| 55 | ### Emacs ### | ||
| 56 | |||
| 57 | *~ | ||
| 58 | \#*\# | ||
| 59 | /.emacs.desktop | ||
| 60 | /.emacs.desktop.lock | ||
| 61 | .elc | ||
| 62 | auto-save-list | ||
| 63 | tramp | ||
| 64 | |||
| 65 | |||
| 66 | ### vim ### | ||
| 67 | |||
| 68 | .*.sw[a-z] | ||
| 69 | *.un~ | ||
| 70 | Session.vim | ||
| 71 | |||
| 72 | |||
| 73 | ### TextMate ### | ||
| 74 | |||
| 75 | *.tmproj | ||
| 76 | *.tmproject | ||
| 77 | tmtags | ||
| 78 | |||
| 79 | |||
| 80 | ### Linux ### | ||
| 81 | |||
| 82 | .* | ||
| 83 | !.gitignore | ||
| 84 | !.htaccess | ||
| 85 | *~ | ||
| 86 | |||
| 87 | # KDE | ||
| 88 | .directory | ||
| 89 | |||
| 90 | |||
| 91 | ### Windows ### | ||
| 92 | |||
| 93 | # Windows image file caches | ||
| 94 | Thumbs.db | ||
| 95 | |||
| 96 | # Folder config file | ||
| 97 | Desktop.ini | ||
| 98 | |||
| 99 | |||
| 100 | ### SVN ### | ||
| 101 | |||
| 102 | .svn/ | ||
| 103 | |||
| 104 | /dummy.php | ||
| 105 | /wp-content/uploads/ | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
.htaccess
0 → 100644
14-131-009c - W5 Online Ad Production/SWFs from Chris Gardner/Big Box/sjh_2014_300x250_v2.html
0 → 100644
| 1 | <!DOCTYPE html> | ||
| 2 | <html> | ||
| 3 | <head> | ||
| 4 | <meta charset="UTF-8"> | ||
| 5 | <title>sjh_2014_300x250_v2</title> | ||
| 6 | <style type="text/css" media="screen"> | ||
| 7 | html, body { height:100%; background-color: #ffffff;} | ||
| 8 | body { margin:0; padding:0; overflow:hidden; } | ||
| 9 | #flashContent { width:100%; height:100%; } | ||
| 10 | </style> | ||
| 11 | </head> | ||
| 12 | <body> | ||
| 13 | <div id="flashContent"> | ||
| 14 | <object type="application/x-shockwave-flash" data="sjh_2014_300x250_v2.swf" width="300" height="250" id="sjh_2014_300x250_v2" style="float: none; vertical-align:middle"> | ||
| 15 | <param name="movie" value="sjh_2014_300x250_v2.swf" /> | ||
| 16 | <param name="quality" value="high" /> | ||
| 17 | <param name="bgcolor" value="#ffffff" /> | ||
| 18 | <param name="play" value="true" /> | ||
| 19 | <param name="loop" value="true" /> | ||
| 20 | <param name="wmode" value="window" /> | ||
| 21 | <param name="scale" value="showall" /> | ||
| 22 | <param name="menu" value="true" /> | ||
| 23 | <param name="devicefont" value="false" /> | ||
| 24 | <param name="salign" value="" /> | ||
| 25 | <param name="allowScriptAccess" value="sameDomain" /> | ||
| 26 | <a href="http://www.adobe.com/go/getflash"> | ||
| 27 | <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /> | ||
| 28 | </a> | ||
| 29 | </object> | ||
| 30 | </div> | ||
| 31 | </body> | ||
| 32 | </html> |
14-131-009c - W5 Online Ad Production/SWFs from Chris Gardner/Big Box/sjh_2014_300x250_v2.swf
0 → 100644
No preview for this file type
| 1 | <!DOCTYPE html> | ||
| 2 | <html> | ||
| 3 | <head> | ||
| 4 | <meta charset="UTF-8"> | ||
| 5 | <title>sjh_2014_300x600</title> | ||
| 6 | <style type="text/css" media="screen"> | ||
| 7 | html, body { height:100%; background-color: #32bcd5;} | ||
| 8 | body { margin:0; padding:0; overflow:hidden; } | ||
| 9 | #flashContent { width:100%; height:100%; } | ||
| 10 | </style> | ||
| 11 | </head> | ||
| 12 | <body> | ||
| 13 | <div id="flashContent"> | ||
| 14 | <object type="application/x-shockwave-flash" data="sjh_2014_300x600.swf" width="300" height="600" id="sjh_2014_300x600" style="float: none; vertical-align:middle"> | ||
| 15 | <param name="movie" value="sjh_2014_300x600.swf" /> | ||
| 16 | <param name="quality" value="high" /> | ||
| 17 | <param name="bgcolor" value="#32bcd5" /> | ||
| 18 | <param name="play" value="true" /> | ||
| 19 | <param name="loop" value="true" /> | ||
| 20 | <param name="wmode" value="window" /> | ||
| 21 | <param name="scale" value="showall" /> | ||
| 22 | <param name="menu" value="true" /> | ||
| 23 | <param name="devicefont" value="false" /> | ||
| 24 | <param name="salign" value="" /> | ||
| 25 | <param name="allowScriptAccess" value="sameDomain" /> | ||
| 26 | <a href="http://www.adobe.com/go/getflash"> | ||
| 27 | <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /> | ||
| 28 | </a> | ||
| 29 | </object> | ||
| 30 | </div> | ||
| 31 | </body> | ||
| 32 | </html> |
14-131-009c - W5 Online Ad Production/SWFs from Chris Gardner/Double skyscraper/sjh_2014_300x600.swf
0 → 100644
No preview for this file type
| 1 | <!DOCTYPE html> | ||
| 2 | <html> | ||
| 3 | <head> | ||
| 4 | <meta charset="UTF-8"> | ||
| 5 | <title>sjh_2014</title> | ||
| 6 | <style type="text/css" media="screen"> | ||
| 7 | html, body { height:100%; background-color: #ffffff;} | ||
| 8 | body { margin:0; padding:0; overflow:hidden; } | ||
| 9 | #flashContent { width:100%; height:100%; } | ||
| 10 | </style> | ||
| 11 | </head> | ||
| 12 | <body> | ||
| 13 | <div id="flashContent"> | ||
| 14 | <object type="application/x-shockwave-flash" data="sjh_2014.swf" width="728" height="90" id="sjh_2014" style="float: none; vertical-align:middle"> | ||
| 15 | <param name="movie" value="sjh_2014.swf" /> | ||
| 16 | <param name="quality" value="high" /> | ||
| 17 | <param name="bgcolor" value="#ffffff" /> | ||
| 18 | <param name="play" value="true" /> | ||
| 19 | <param name="loop" value="true" /> | ||
| 20 | <param name="wmode" value="window" /> | ||
| 21 | <param name="scale" value="showall" /> | ||
| 22 | <param name="menu" value="true" /> | ||
| 23 | <param name="devicefont" value="false" /> | ||
| 24 | <param name="salign" value="" /> | ||
| 25 | <param name="allowScriptAccess" value="sameDomain" /> | ||
| 26 | <a href="http://www.adobe.com/go/getflash"> | ||
| 27 | <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /> | ||
| 28 | </a> | ||
| 29 | </object> | ||
| 30 | </div> | ||
| 31 | </body> | ||
| 32 | </html> |
No preview for this file type
| 1 | <!DOCTYPE html> | ||
| 2 | <html> | ||
| 3 | <head> | ||
| 4 | <meta charset="UTF-8"> | ||
| 5 | <title>sjh_2014</title> | ||
| 6 | <style type="text/css" media="screen"> | ||
| 7 | html, body { | ||
| 8 | height: 100%; | ||
| 9 | background-color: #ffffff; | ||
| 10 | } | ||
| 11 | |||
| 12 | body { | ||
| 13 | margin: 0; | ||
| 14 | padding: 0; | ||
| 15 | overflow: hidden; | ||
| 16 | } | ||
| 17 | |||
| 18 | #flashContent { | ||
| 19 | width: 100%; | ||
| 20 | height: 100%; | ||
| 21 | } | ||
| 22 | |||
| 23 | #ad2-container { | ||
| 24 | position: absolute; | ||
| 25 | top: 0; | ||
| 26 | left: 330px; | ||
| 27 | } | ||
| 28 | |||
| 29 | #ad3-container { | ||
| 30 | position: absolute; | ||
| 31 | top: 120px; | ||
| 32 | left: 330px; | ||
| 33 | } | ||
| 34 | </style> | ||
| 35 | </head> | ||
| 36 | <body> | ||
| 37 | <div id="flashContent"> | ||
| 38 | <div id="ad1-container"> | ||
| 39 | <object type="application/x-shockwave-flash" data="sjh_2014_300x600.swf" width="300" height="600" | ||
| 40 | id="sjh_2014_300x600" style="float: none; vertical-align:middle"> | ||
| 41 | <param name="movie" value="sjh_2014_300x600.swf"/> | ||
| 42 | <param name="quality" value="high"/> | ||
| 43 | <param name="bgcolor" value="#32bcd5"/> | ||
| 44 | <param name="play" value="true"/> | ||
| 45 | <param name="loop" value="true"/> | ||
| 46 | <param name="wmode" value="window"/> | ||
| 47 | <param name="scale" value="showall"/> | ||
| 48 | <param name="menu" value="true"/> | ||
| 49 | <param name="devicefont" value="false"/> | ||
| 50 | <param name="salign" value=""/> | ||
| 51 | <param name="allowScriptAccess" value="sameDomain"/> | ||
| 52 | <a href="http://www.adobe.com/go/getflash"> | ||
| 53 | <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" | ||
| 54 | alt="Get Adobe Flash player"/> | ||
| 55 | </a> | ||
| 56 | </object> | ||
| 57 | </div> | ||
| 58 | |||
| 59 | <div id="ad2-container"> | ||
| 60 | <object type="application/x-shockwave-flash" data="sjh_2014.swf" width="728" height="90" id="sjh_2014" | ||
| 61 | style="float: none; vertical-align:middle"> | ||
| 62 | <param name="movie" value="sjh_2014.swf"/> | ||
| 63 | <param name="quality" value="high"/> | ||
| 64 | <param name="bgcolor" value="#ffffff"/> | ||
| 65 | <param name="play" value="true"/> | ||
| 66 | <param name="loop" value="true"/> | ||
| 67 | <param name="wmode" value="window"/> | ||
| 68 | <param name="scale" value="showall"/> | ||
| 69 | <param name="menu" value="true"/> | ||
| 70 | <param name="devicefont" value="false"/> | ||
| 71 | <param name="salign" value=""/> | ||
| 72 | <param name="allowScriptAccess" value="sameDomain"/> | ||
| 73 | <a href="http://www.adobe.com/go/getflash"> | ||
| 74 | <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" | ||
| 75 | alt="Get Adobe Flash player"/> | ||
| 76 | </a> | ||
| 77 | </object> | ||
| 78 | </div> | ||
| 79 | |||
| 80 | <div id="ad3-container"> | ||
| 81 | <object type="application/x-shockwave-flash" data="sjh_2014_300x250_v2.swf" width="300" height="250" | ||
| 82 | id="sjh_2014_300x250_v2" style="float: none; vertical-align:middle"> | ||
| 83 | <param name="movie" value="sjh_2014_300x250_v2.swf"/> | ||
| 84 | <param name="quality" value="high"/> | ||
| 85 | <param name="bgcolor" value="#ffffff"/> | ||
| 86 | <param name="play" value="true"/> | ||
| 87 | <param name="loop" value="true"/> | ||
| 88 | <param name="wmode" value="window"/> | ||
| 89 | <param name="scale" value="showall"/> | ||
| 90 | <param name="menu" value="true"/> | ||
| 91 | <param name="devicefont" value="false"/> | ||
| 92 | <param name="salign" value=""/> | ||
| 93 | <param name="allowScriptAccess" value="sameDomain"/> | ||
| 94 | <a href="http://www.adobe.com/go/getflash"> | ||
| 95 | <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" | ||
| 96 | alt="Get Adobe Flash player"/> | ||
| 97 | </a> | ||
| 98 | </object> | ||
| 99 | </div> | ||
| 100 | </div> | ||
| 101 | </body> | ||
| 102 | </html> |
No preview for this file type
No preview for this file type
No preview for this file type
TzLinker.js
0 → 100644
| 1 | TzLinker = function() { | ||
| 2 | var Changer; | ||
| 3 | var Disp; | ||
| 4 | |||
| 5 | var domain; | ||
| 6 | |||
| 7 | var hardSwitch = function() { | ||
| 8 | Disp.firstChild.nodeValue = ''; | ||
| 9 | parent.mainFrame.location.href = '/home.html'; | ||
| 10 | } | ||
| 11 | |||
| 12 | var Switch = function(e) { | ||
| 13 | if (e.target.options.selectedIndex == 0) { | ||
| 14 | return hardSwitch(); | ||
| 15 | } | ||
| 16 | |||
| 17 | Disp.firstChild.nodeValue = '?id=' + e.target.value; | ||
| 18 | |||
| 19 | parent.mainFrame.location.href = '/' + e.target.options[e.target.options.selectedIndex].text + '/publish/'; | ||
| 20 | } | ||
| 21 | |||
| 22 | return { | ||
| 23 | init: function() { | ||
| 24 | Changer = document.getElementById('menu'); | ||
| 25 | addEvent(Changer, 'change', Switch); | ||
| 26 | |||
| 27 | Disp = document.getElementById('TzURL').getElementsByTagName('dd')[0].getElementsByTagName('span')[0]; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | }(); | ||
| 31 | |||
| 32 | addEvent(window, 'load', TzLinker.init); | ||
| 33 | |||
| 34 |
addEvent.js
0 → 100644
| 1 | function addEvent(element, type, handler) { | ||
| 2 | // assign each event handler a unique ID | ||
| 3 | if (!handler.$$guid) handler.$$guid = addEvent.guid++; | ||
| 4 | // create a hash table of event types for the element | ||
| 5 | if (!element.events) element.events = {}; | ||
| 6 | // create a hash table of event handlers for each element/event pair | ||
| 7 | var handlers = element.events[type]; | ||
| 8 | if (!handlers) { | ||
| 9 | handlers = element.events[type] = {}; | ||
| 10 | // store the existing event handler (if there is one) | ||
| 11 | if (element["on" + type]) { | ||
| 12 | handlers[0] = element["on" + type]; | ||
| 13 | } | ||
| 14 | } | ||
| 15 | // store the event handler in the hash table | ||
| 16 | handlers[handler.$$guid] = handler; | ||
| 17 | // assign a global event handler to do all the work | ||
| 18 | element["on" + type] = handleEvent; | ||
| 19 | }; | ||
| 20 | // a counter used to create unique IDs | ||
| 21 | addEvent.guid = 1; | ||
| 22 | |||
| 23 | function removeEvent(element, type, handler) { | ||
| 24 | // delete the event handler from the hash table | ||
| 25 | if (element.events && element.events[type]) { | ||
| 26 | delete element.events[type][handler.$$guid]; | ||
| 27 | } | ||
| 28 | }; | ||
| 29 | |||
| 30 | function handleEvent(event) { | ||
| 31 | // grab the event object (IE uses a global event object) | ||
| 32 | event = event || window.event; | ||
| 33 | // get a reference to the hash table of event handlers | ||
| 34 | var handlers = this.events[event.type]; | ||
| 35 | // execute each event handler | ||
| 36 | for (var i in handlers) { | ||
| 37 | this.$$handleEvent = handlers[i]; | ||
| 38 | this.$$handleEvent(event); | ||
| 39 | } | ||
| 40 | }; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
banner resources/ClickTag Validator.webloc
0 → 100644
banner resources/Corus 2010-01-25.pdf
0 → 100644
No preview for this file type
banner resources/Flash Examples.webloc
0 → 100644
No preview for this file type
banner resources/NCU online specs.doc
0 → 100644
No preview for this file type
No preview for this file type
banner resources/clicktagger
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
banner resources/expanding mockup/index.html
0 → 100755
| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
| 2 | <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> | ||
| 3 | <head> | ||
| 4 | <title>CBV 2012 Spring</title> | ||
| 5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | ||
| 6 | <script type="text/javascript" src="swfobject.js"></script> | ||
| 7 | <script type="text/javascript"> | ||
| 8 | //var flashvars = {clickTag1:"http://www.flashadbook.com",clickTAG2:"http://www.jasonfincanon.com"}; | ||
| 9 | var flashvars = {clickTag:"https://cicbv.ca"}; | ||
| 10 | swfobject.embedSWF("en_300x250_cbv_2012spring_c01_AS3_unexpanded.swf", "ad300x250a", "300", "250", "9.0.0", false, flashvars); | ||
| 11 | swfobject.embedSWF("en_300x250_cbv_2012spring_c01_AS3_expanded.swf", "ad600x250a", "600", "250", "9.0.0", false, flashvars); | ||
| 12 | swfobject.embedSWF("en_300x250_cbv_2012spring_c01_AS3_unexpanded.swf", "ad300x250b", "300", "250", "9.0.0", false, flashvars); | ||
| 13 | swfobject.embedSWF("en_300x250_cbv_2012spring_c01_AS3_expanded.swf", "ad600x250b", "600", "250", "9.0.0", false, flashvars); | ||
| 14 | |||
| 15 | window.onload = function(){ | ||
| 16 | initExpansionAd('ad300x250aContainer', 'ad600x250aContainer'); | ||
| 17 | initExpansionAd('ad300x250bContainer', 'ad600x250bContainer'); | ||
| 18 | }; | ||
| 19 | var initExpansionAd = function(ad, exp){ | ||
| 20 | var Unexpanded = document.getElementById(ad); | ||
| 21 | var Expanded = document.getElementById(exp); | ||
| 22 | Unexpanded.onmouseover = function() {Expanded.style.display = 'block';Unexpanded.style.display = 'none';} | ||
| 23 | Expanded.onmouseout = function() {Expanded.style.display = 'none';Unexpanded.style.display = 'block';} | ||
| 24 | }; | ||
| 25 | </script> | ||
| 26 | <style type="text/css"> | ||
| 27 | .unexpanded, .expanded {position: absolute;margin-top: 0;} | ||
| 28 | .unexpanded { left: 400px; } | ||
| 29 | .expanded {left: 100px;display: none;} | ||
| 30 | #ad300x250aContainer, #ad600x250aContainer{top: 10px;} | ||
| 31 | #ad300x250bContainer, #ad600x250bContainer{top: 310px;} | ||
| 32 | </style> | ||
| 33 | </head> | ||
| 34 | <body> | ||
| 35 | |||
| 36 | |||
| 37 | <div class="unexpanded" id="ad300x250aContainer"> | ||
| 38 | <div id="ad300x250a"> | ||
| 39 | <h1>Please install Adobe's free Flash Player.</h1> | ||
| 40 | <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p> | ||
| 41 | </div> | ||
| 42 | </div> | ||
| 43 | <div class="expanded" id="ad600x250aContainer"> | ||
| 44 | <div id="ad600x250a"> | ||
| 45 | <h1>Please install Adobe's free Flash Player.</h1> | ||
| 46 | <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p> | ||
| 47 | </div> | ||
| 48 | </div> | ||
| 49 | |||
| 50 | <div class="unexpanded" id="ad300x250bContainer"> | ||
| 51 | <div id="ad300x250b"> | ||
| 52 | <h1>Please install Adobe's free Flash Player.</h1> | ||
| 53 | <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p> | ||
| 54 | </div> | ||
| 55 | </div> | ||
| 56 | <div class="expanded" id="ad600x250bContainer"> | ||
| 57 | <div id="ad600x250b"> | ||
| 58 | <h1>Please install Adobe's free Flash Player.</h1> | ||
| 59 | <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p> | ||
| 60 | </div> | ||
| 61 | </div> | ||
| 62 | |||
| 63 | |||
| 64 | </body> | ||
| 65 | </html> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /* SWFObject v2.2 <http://code.google.com/p/swfobject/> | ||
| 2 | is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> | ||
| 3 | */ | ||
| 4 | var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}(); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
banner resources/eyeReturn_Templates/Portrait/AS2/Expanded Modules/Expanded_Primary_490x480.fla
0 → 100755
No preview for this file type
banner resources/eyeReturn_Templates/Portrait/AS2/Expanded Modules/Expanded_Primary_490x480_as2.swf
0 → 100755
No preview for this file type
banner resources/eyeReturn_Templates/Portrait/AS2/Expanded Modules/Expanded_Secondary_490x240.fla
0 → 100755
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
banner resources/eyeReturn_Templates/Portrait/AS3/Expanded Modules/Expanded_Primary_490x480.fla
0 → 100755
No preview for this file type
banner resources/eyeReturn_Templates/Portrait/AS3/Expanded Modules/Expanded_Primary_490x480.swf
0 → 100755
No preview for this file type
banner resources/eyeReturn_Templates/Portrait/AS3/Expanded Modules/Expanded_Secondary_490x240.fla
0 → 100755
No preview for this file type
banner resources/eyeReturn_Templates/Portrait/AS3/Expanded Modules/Expanded_Secondary_490x240.swf
0 → 100755
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
cache_proxy.php
0 → 100644
| 1 | <?php | ||
| 2 | $accepted_files = Array( | ||
| 3 | 'swf' => 'application/x-shockwave-flash' | ||
| 4 | , 'xml' => 'text/xml' | ||
| 5 | ); | ||
| 6 | |||
| 7 | $filename = ''; | ||
| 8 | if (isset($_GET) && isset($_GET['file'])) { | ||
| 9 | $sep = (substr($_GET['file'], 0, 1) == '/' ? '' : DIRECTORY_SEPARATOR); | ||
| 10 | $filename = dirname(__FILE__) . $sep . $_GET['file']; | ||
| 11 | } else { | ||
| 12 | die; | ||
| 13 | } | ||
| 14 | |||
| 15 | $type = substr($filename, -3); | ||
| 16 | if (!in_array($type, array_keys($accepted_files))) { | ||
| 17 | die; | ||
| 18 | } | ||
| 19 | |||
| 20 | header("Content-type: {$accepted_files[$type]}"); | ||
| 21 | header("Expires: Thu, 01 Jan 1970 00:00:00 GMT, -1 "); | ||
| 22 | header("Cache-Control: no-cache, no-store, must-revalidate"); | ||
| 23 | header("Pragma: no-cache"); | ||
| 24 | |||
| 25 | echo file_get_contents($filename); | ||
| 26 | ?> |
crossdomain.xml
0 → 100644
| 1 | <?xml version="1.0"?> | ||
| 2 | <!DOCTYPE cross-domain-policy SYSTEM | ||
| 3 | "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> | ||
| 4 | |||
| 5 | <cross-domain-policy> | ||
| 6 | <site-control permitted-cross-domain-policies="all"/> | ||
| 7 | <!-- The ones below are not recommended at the root level. | ||
| 8 | The above site-control allows for exceptions within specific | ||
| 9 | directories using policies in those directories. | ||
| 10 | --> | ||
| 11 | |||
| 12 | <allow-access-from domain="*" secure="false"/> | ||
| 13 | <allow-http-request-headers-from domain="*" headers="*" secure="false"/> | ||
| 14 | |||
| 15 | </cross-domain-policy> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
No preview for this file type
eBlast resources/htmlemail1pdf.pdf
0 → 100644
This file is too large to display.
eBlast resources/http--litmus.com.webloc
0 → 100644
No preview for this file type
home.html
0 → 100644
includes/auth.php
0 → 100644
| 1 | <?php | ||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 | include(' loggedin.php'); | ||
| 9 | return; | ||
| 10 | |||
| 11 | |||
| 12 | ?> | ||
| 13 | |||
| 14 | <form method="post"> | ||
| 15 | <dl class="TzMenu"> | ||
| 16 | <dt><label for="username">Username:</label></dt> | ||
| 17 | <dd><input type="text" name="username" id="username" /></dd> | ||
| 18 | </dl> | ||
| 19 | |||
| 20 | <dl class="TzMenu"> | ||
| 21 | <dt><label for="password">Password:</label></dt> | ||
| 22 | <dd><input type="password" name="password" id="password" /></dd> | ||
| 23 | </dl> | ||
| 24 | |||
| 25 | <dl class="TzMenu"> | ||
| 26 | <dt><input type="submit" value=" Log In " /></dt> | ||
| 27 | </dl> | ||
| 28 | </form> | ||
| 29 | |||
| 30 | <script type="text/javascript"> | ||
| 31 | addEvent(window, 'load', function() { | ||
| 32 | document.getElementById('username').select(); | ||
| 33 | }); | ||
| 34 | </script> |
includes/function.php
0 → 100644
| 1 | <?php | ||
| 2 | session_start(); | ||
| 3 | $clientId = $_POST['id']; | ||
| 4 | $dockets_obj = json_decode($_SESSION['lookup']); | ||
| 5 | // error_log('test error'. $dockets_obj); | ||
| 6 | $opt = " "; | ||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | $dockets = Array(); | ||
| 11 | |||
| 12 | |||
| 13 | $opt .= '<option value="home.html">Splash Page</option>'; | ||
| 14 | foreach ($dockets_obj as $docket => $key) { | ||
| 15 | $dockets[$docket] = $key; | ||
| 16 | } | ||
| 17 | ksort($dockets); | ||
| 18 | |||
| 19 | foreach ($dockets as $dir => $md5) { | ||
| 20 | $client = explode("-",$dir); | ||
| 21 | $clientIds = $client[1]; | ||
| 22 | if($clientIds == $clientId ){ | ||
| 23 | |||
| 24 | |||
| 25 | $opt .= '<option value="' . $md5 . '"' .' '. '>' . $dir . '</option>'; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | // error_log('test error'. $opt); | ||
| 29 | echo $opt; | ||
| 30 | die(); |
includes/loggedin.php
0 → 100644
| 1 | <?php | ||
| 2 | if (!isset($_SESSION) && !isset($_SESSION['username'])) { | ||
| 3 | return; | ||
| 4 | } | ||
| 5 | |||
| 6 | |||
| 7 | $dockets = Array(); | ||
| 8 | $dockets_obj = json_decode($_SESSION['lookup']); | ||
| 9 | foreach ($dockets_obj as $docket => $key) { | ||
| 10 | $dockets[$docket] = $key; | ||
| 11 | } | ||
| 12 | ksort($dockets); | ||
| 13 | $id = (isset($_GET['id']) ? '?id=' . $_GET['id'] : ' '); | ||
| 14 | |||
| 15 | foreach ($dockets as $dir => $md5) { | ||
| 16 | $client = explode("-",$dir); | ||
| 17 | $clientIds[] = $client[1]; | ||
| 18 | |||
| 19 | |||
| 20 | |||
| 21 | } | ||
| 22 | $clientIdsGrouped = array_unique($clientIds, SORT_REGULAR); | ||
| 23 | |||
| 24 | // var_dump($clientIdsGrouped); | ||
| 25 | |||
| 26 | |||
| 27 | ?> | ||
| 28 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> | ||
| 29 | |||
| 30 | |||
| 31 | |||
| 32 | <?php $json = file_get_contents('includes/names.json'); | ||
| 33 | $names = json_decode($json); | ||
| 34 | |||
| 35 | |||
| 36 | ?> | ||
| 37 | |||
| 38 | <dl class="TzMenu"> | ||
| 39 | <dt><label for="client_menu">Clients</label></dt> | ||
| 40 | <dd><select id="client_menu" name="client_menu"> | ||
| 41 | <option value="">Pick</option> | ||
| 42 | <?php | ||
| 43 | /* Figure out clients */ | ||
| 44 | |||
| 45 | foreach ($clientIdsGrouped as $key => $clientId ) { | ||
| 46 | if($names->$clientId == null){ $clientName = $clientId; }else{$clientName = $names->$clientId;}; | ||
| 47 | |||
| 48 | echo '<option value="' . $clientId. '"' .' '. '>' .$clientName . '</option>'; | ||
| 49 | } | ||
| 50 | |||
| 51 | ?> | ||
| 52 | </select></dd> | ||
| 53 | </dl> | ||
| 54 | |||
| 55 | |||
| 56 | <dl class="TzMenu"> | ||
| 57 | <dt><label for="menu">Project</label></dt> | ||
| 58 | <dd><select id="menu" name="menu"> | ||
| 59 | <option value="home.html">Splash Page</option> | ||
| 60 | <?php | ||
| 61 | |||
| 62 | ?> | ||
| 63 | </select></dd> | ||
| 64 | </dl> | ||
| 65 | |||
| 66 | <dl class="TzMenu" id="TzURL"> | ||
| 67 | <dt style="font-weight: bold;">URL:</dt> | ||
| 68 | <dd>http://<?php echo $_GET['d'];?>/<span><?php echo $id;?></span></dd> | ||
| 69 | </dl> | ||
| 70 | |||
| 71 | |||
| 72 | <script type = 'text/javascript'> | ||
| 73 | |||
| 74 | $('#client_menu').on('change',function(){ | ||
| 75 | populateSelect() | ||
| 76 | }); | ||
| 77 | |||
| 78 | |||
| 79 | function populateSelect(){ | ||
| 80 | |||
| 81 | cat= $('#client_menu').val(); | ||
| 82 | menu = $.ajax({ url: 'includes/function.php', | ||
| 83 | data: {id: cat}, | ||
| 84 | type: 'post', | ||
| 85 | success: function(output) { | ||
| 86 | // alert(output); | ||
| 87 | $('#menu').html(''); | ||
| 88 | $('#menu').append(output) | ||
| 89 | |||
| 90 | } | ||
| 91 | }); | ||
| 92 | |||
| 93 | |||
| 94 | |||
| 95 | |||
| 96 | |||
| 97 | } | ||
| 98 | |||
| 99 | |||
| 100 | |||
| 101 | </script> | ||
| 102 | |||
| 103 | <script type="text/javascript" src="TzLinker.js"></script> |
includes/names.json
0 → 100644
| 1 | { | ||
| 2 | "011":"OSRAM Sylvania Ltd(CML)" | ||
| 3 | , | ||
| 4 | |||
| 5 | "013":"Transition Science Inc." | ||
| 6 | , | ||
| 7 | |||
| 8 | "014":"CSI Global Education Inc." | ||
| 9 | , | ||
| 10 | |||
| 11 | "022":"RL Solutions" | ||
| 12 | , | ||
| 13 | |||
| 14 | "023":"The Canadian Institute of Chartered Business Valuators" | ||
| 15 | , | ||
| 16 | |||
| 17 | "025":"CUCC- CBOS" | ||
| 18 | , | ||
| 19 | |||
| 20 | "030":"The Fire Employees Credit Union" | ||
| 21 | , | ||
| 22 | |||
| 23 | "040":"Northern Credit Union" | ||
| 24 | , | ||
| 25 | |||
| 26 | "050":"Tenzing Internal" | ||
| 27 | , | ||
| 28 | |||
| 29 | "095":"Libro Financial Group" | ||
| 30 | , | ||
| 31 | |||
| 32 | "104":"FirstOntario Credit Union" | ||
| 33 | , | ||
| 34 | |||
| 35 | "116":"PS Production Services" | ||
| 36 | , | ||
| 37 | |||
| 38 | "120":"Russell Investments" | ||
| 39 | , | ||
| 40 | |||
| 41 | "124":"Alterna Savings" | ||
| 42 | , | ||
| 43 | |||
| 44 | "131":"St. Joseph Healthcare Hamilton" | ||
| 45 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
index.php
0 → 100644
| 1 | <?php | ||
| 2 | |||
| 3 | session_start(); | ||
| 4 | |||
| 5 | $dockets = Array(); | ||
| 6 | $valid = 'home.html'; | ||
| 7 | $id = ''; | ||
| 8 | |||
| 9 | $handle = opendir('.'); | ||
| 10 | while ($file = readdir($handle)) { | ||
| 11 | if (is_dir($file) && strlen($file) > 2 && $file{2} == '-') { | ||
| 12 | $dockets[$file] = md5($file); | ||
| 13 | |||
| 14 | if (isset($_GET['id']) && $_GET['id'] == md5($file)) { | ||
| 15 | $valid = $file . '/publish/'; | ||
| 16 | $id = '&id=' . $_GET['id']; | ||
| 17 | } | ||
| 18 | } | ||
| 19 | } | ||
| 20 | closedir($handle); | ||
| 21 | |||
| 22 | $_SESSION['lookup'] = json_encode($dockets); | ||
| 23 | |||
| 24 | |||
| 25 | ?> | ||
| 26 | <?php header("Access-Control-Allow-Origin", "*"); ?> | ||
| 27 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> | ||
| 28 | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
| 29 | <head> | ||
| 30 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||
| 31 | <title>Tenzing Communications Inc.</title> | ||
| 32 | <style type="text/css"> | ||
| 33 | body { | ||
| 34 | margin:0; | ||
| 35 | padding:0; | ||
| 36 | background-color: #3b0d32; | ||
| 37 | color: #777; | ||
| 38 | } | ||
| 39 | </style> | ||
| 40 | |||
| 41 | <script type="text/javascript"> | ||
| 42 | // document.domain = 'gotenzing.com'; | ||
| 43 | </script> | ||
| 44 | </head> | ||
| 45 | |||
| 46 | <frameset rows="*,75" frameborder="no" border="0" framespacing="0"> | ||
| 47 | <frame src="<?php echo $valid;?>" name="mainFrame" id="mainFrame" title="mainFrame" /> | ||
| 48 | <frame src="menu.php?d=<?php echo $_SERVER['HTTP_HOST']. $id;?>" name="bottomFrame" scrolling="No" noresize="noresize" id="bottomFrame" title="bottomFrame" /> | ||
| 49 | <?php /* | ||
| 50 | <frame src="http://banners.cvs.gotenzing.com/menu.php?d=<?php echo $_SERVER['HTTP_HOST'];?>" name="bottomFrame" scrolling="No" noresize="noresize" id="bottomFrame" title="bottomFrame" /> | ||
| 51 | */ ?> | ||
| 52 | </frameset> | ||
| 53 | <noframes> | ||
| 54 | <body> | ||
| 55 | </body> | ||
| 56 | |||
| 57 | </noframes> | ||
| 58 | </html> |
menu.php
0 → 100644
| 1 | <?php | ||
| 2 | session_start(); | ||
| 3 | $db = new mysqli('localhost', 'root', 'root'); | ||
| 4 | ?> | ||
| 5 | |||
| 6 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
| 7 | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
| 8 | <head> | ||
| 9 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||
| 10 | <title>Tenzing Communications Inc.</title> | ||
| 11 | |||
| 12 | <style type="text/css"> | ||
| 13 | body, h1 { | ||
| 14 | margin: 0; | ||
| 15 | padding: 0; | ||
| 16 | background-color: #3B0D32; | ||
| 17 | color: #FFF; | ||
| 18 | font: 11px/120% 'Trebuchet MS', Verdana, Arial, sans-serif; | ||
| 19 | } | ||
| 20 | |||
| 21 | h1 { | ||
| 22 | font-size: 14px; | ||
| 23 | font-weight: bold; | ||
| 24 | padding: 0 0 2px 0; | ||
| 25 | } | ||
| 26 | select { font: 11px/120% 'Trebuchet MS', Verdana, Arial, sans-serif; } | ||
| 27 | label { | ||
| 28 | font-weight: bold; | ||
| 29 | vertical-align: 25%; | ||
| 30 | } | ||
| 31 | |||
| 32 | .TzMenu { | ||
| 33 | float: left; | ||
| 34 | margin: 15px; | ||
| 35 | height: 65px; | ||
| 36 | } | ||
| 37 | ul.TzMenu { | ||
| 38 | list-style: none; | ||
| 39 | padding-left: 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | #TzLogo { | ||
| 43 | float: right; | ||
| 44 | width: 259px; | ||
| 45 | } | ||
| 46 | |||
| 47 | #submit { margin-left: 6px; } | ||
| 48 | |||
| 49 | dd { margin-left: 0; } | ||
| 50 | </style> | ||
| 51 | |||
| 52 | <script type="text/javascript" src="addEvent.js"></script> | ||
| 53 | |||
| 54 | |||
| 55 | </head> | ||
| 56 | |||
| 57 | <body> | ||
| 58 | <?php | ||
| 59 | |||
| 60 | include('includes/loggedin.php'); | ||
| 61 | |||
| 62 | ?> | ||
| 63 | |||
| 64 | <div id="TzLogo"> | ||
| 65 | <img src="tenzing.gif" width="259" height="75" alt="Tenzing" /> | ||
| 66 | </div> | ||
| 67 | </body> | ||
| 68 | </html> |
sherpa.gif
0 → 100644
32.8 KB
tenzing.gif
0 → 100644
1.51 KB
-
Please register or sign in to post a comment