canvasengine 2.0.0-beta.4 → 2.0.0-beta.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/DebugRenderer-BxfW34YG.js +172 -0
  2. package/dist/DebugRenderer-BxfW34YG.js.map +1 -0
  3. package/dist/components/Button.d.ts +183 -0
  4. package/dist/components/Button.d.ts.map +1 -0
  5. package/dist/components/Canvas.d.ts +18 -0
  6. package/dist/components/Canvas.d.ts.map +1 -0
  7. package/dist/components/DOMElement.d.ts +44 -0
  8. package/dist/components/DOMElement.d.ts.map +1 -0
  9. package/dist/components/Graphic.d.ts +65 -0
  10. package/dist/components/Graphic.d.ts.map +1 -0
  11. package/dist/components/Joystick.d.ts +36 -0
  12. package/dist/components/Joystick.d.ts.map +1 -0
  13. package/dist/components/NineSliceSprite.d.ts +17 -0
  14. package/dist/components/NineSliceSprite.d.ts.map +1 -0
  15. package/dist/components/ParticleEmitter.d.ts +5 -0
  16. package/dist/components/ParticleEmitter.d.ts.map +1 -0
  17. package/dist/components/Scene.d.ts +2 -0
  18. package/dist/components/Scene.d.ts.map +1 -0
  19. package/dist/components/Text.d.ts +26 -0
  20. package/dist/components/Text.d.ts.map +1 -0
  21. package/dist/components/TilingSprite.d.ts +18 -0
  22. package/dist/components/TilingSprite.d.ts.map +1 -0
  23. package/dist/components/Video.d.ts +15 -0
  24. package/dist/components/Video.d.ts.map +1 -0
  25. package/dist/components/index.d.ts +18 -0
  26. package/dist/components/index.d.ts.map +1 -0
  27. package/dist/components/types/DisplayObject.d.ts +110 -0
  28. package/dist/components/types/DisplayObject.d.ts.map +1 -0
  29. package/dist/components/types/MouseEvent.d.ts +4 -0
  30. package/dist/components/types/MouseEvent.d.ts.map +1 -0
  31. package/dist/components/types/Spritesheet.d.ts +248 -0
  32. package/dist/components/types/Spritesheet.d.ts.map +1 -0
  33. package/dist/components/types/index.d.ts +5 -0
  34. package/dist/components/types/index.d.ts.map +1 -0
  35. package/dist/directives/Controls.d.ts +113 -0
  36. package/dist/directives/Controls.d.ts.map +1 -0
  37. package/dist/directives/ControlsBase.d.ts +198 -0
  38. package/dist/directives/ControlsBase.d.ts.map +1 -0
  39. package/dist/directives/Drag.d.ts +70 -0
  40. package/dist/directives/Drag.d.ts.map +1 -0
  41. package/dist/directives/Flash.d.ts +117 -0
  42. package/dist/directives/Flash.d.ts.map +1 -0
  43. package/dist/directives/GamepadControls.d.ts +225 -0
  44. package/dist/directives/GamepadControls.d.ts.map +1 -0
  45. package/dist/directives/JoystickControls.d.ts +172 -0
  46. package/dist/directives/JoystickControls.d.ts.map +1 -0
  47. package/dist/directives/KeyboardControls.d.ts +219 -0
  48. package/dist/directives/KeyboardControls.d.ts.map +1 -0
  49. package/dist/directives/Scheduler.d.ts +36 -0
  50. package/dist/directives/Scheduler.d.ts.map +1 -0
  51. package/dist/directives/Shake.d.ts +98 -0
  52. package/dist/directives/Shake.d.ts.map +1 -0
  53. package/dist/directives/Sound.d.ts +26 -0
  54. package/dist/directives/Sound.d.ts.map +1 -0
  55. package/dist/directives/Transition.d.ts +11 -0
  56. package/dist/directives/Transition.d.ts.map +1 -0
  57. package/dist/directives/ViewportCull.d.ts +12 -0
  58. package/dist/directives/ViewportCull.d.ts.map +1 -0
  59. package/dist/directives/ViewportFollow.d.ts +19 -0
  60. package/dist/directives/ViewportFollow.d.ts.map +1 -0
  61. package/dist/directives/index.d.ts +13 -0
  62. package/dist/directives/index.d.ts.map +1 -0
  63. package/dist/engine/animation.d.ts +73 -0
  64. package/dist/engine/animation.d.ts.map +1 -0
  65. package/dist/engine/bootstrap.d.ts +16 -0
  66. package/dist/engine/bootstrap.d.ts.map +1 -0
  67. package/dist/engine/directive.d.ts +14 -0
  68. package/dist/engine/directive.d.ts.map +1 -0
  69. package/dist/engine/reactive.d.ts +105 -0
  70. package/dist/engine/reactive.d.ts.map +1 -0
  71. package/dist/engine/signal.d.ts +72 -0
  72. package/dist/engine/signal.d.ts.map +1 -0
  73. package/dist/engine/trigger.d.ts +54 -0
  74. package/dist/engine/trigger.d.ts.map +1 -0
  75. package/dist/engine/utils.d.ts +90 -0
  76. package/dist/engine/utils.d.ts.map +1 -0
  77. package/dist/hooks/addContext.d.ts +2 -0
  78. package/dist/hooks/addContext.d.ts.map +1 -0
  79. package/dist/hooks/useProps.d.ts +42 -0
  80. package/dist/hooks/useProps.d.ts.map +1 -0
  81. package/dist/hooks/useRef.d.ts +5 -0
  82. package/dist/hooks/useRef.d.ts.map +1 -0
  83. package/dist/index-BnuKipxl.js +12568 -0
  84. package/dist/index-BnuKipxl.js.map +1 -0
  85. package/dist/index.d.ts +15 -1083
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.global.js +29 -0
  88. package/dist/index.global.js.map +1 -0
  89. package/dist/index.js +81 -3041
  90. package/dist/index.js.map +1 -1
  91. package/dist/utils/Ease.d.ts +17 -0
  92. package/dist/utils/Ease.d.ts.map +1 -0
  93. package/dist/utils/GlobalAssetLoader.d.ts +141 -0
  94. package/dist/utils/GlobalAssetLoader.d.ts.map +1 -0
  95. package/dist/utils/RadialGradient.d.ts +58 -0
  96. package/dist/utils/RadialGradient.d.ts.map +1 -0
  97. package/dist/utils/functions.d.ts +2 -0
  98. package/dist/utils/functions.d.ts.map +1 -0
  99. package/package.json +13 -7
  100. package/src/components/Button.ts +396 -0
  101. package/src/components/Canvas.ts +61 -45
  102. package/src/components/Container.ts +21 -2
  103. package/src/components/DOMContainer.ts +123 -0
  104. package/src/components/DOMElement.ts +421 -0
  105. package/src/components/DisplayObject.ts +350 -197
  106. package/src/components/Graphic.ts +200 -34
  107. package/src/components/Joystick.ts +363 -0
  108. package/src/components/Mesh.ts +222 -0
  109. package/src/components/NineSliceSprite.ts +4 -1
  110. package/src/components/ParticleEmitter.ts +12 -8
  111. package/src/components/Sprite.ts +306 -30
  112. package/src/components/Text.ts +125 -18
  113. package/src/components/Video.ts +110 -0
  114. package/src/components/Viewport.ts +59 -43
  115. package/src/components/index.ts +8 -2
  116. package/src/components/types/DisplayObject.ts +34 -0
  117. package/src/components/types/Spritesheet.ts +0 -118
  118. package/src/directives/Controls.ts +254 -0
  119. package/src/directives/ControlsBase.ts +266 -0
  120. package/src/directives/Drag.ts +357 -52
  121. package/src/directives/Flash.ts +419 -0
  122. package/src/directives/GamepadControls.ts +537 -0
  123. package/src/directives/JoystickControls.ts +396 -0
  124. package/src/directives/KeyboardControls.ts +66 -424
  125. package/src/directives/Shake.ts +295 -0
  126. package/src/directives/Sound.ts +94 -31
  127. package/src/directives/ViewportFollow.ts +35 -7
  128. package/src/directives/index.ts +12 -6
  129. package/src/engine/animation.ts +175 -21
  130. package/src/engine/bootstrap.ts +23 -3
  131. package/src/engine/directive.ts +2 -2
  132. package/src/engine/reactive.ts +780 -177
  133. package/src/engine/signal.ts +35 -4
  134. package/src/engine/trigger.ts +34 -7
  135. package/src/engine/utils.ts +19 -3
  136. package/src/hooks/useProps.ts +1 -1
  137. package/src/index.ts +4 -2
  138. package/src/utils/GlobalAssetLoader.ts +257 -0
  139. package/src/utils/functions.ts +7 -0
  140. package/testing/index.ts +12 -0
  141. package/tsconfig.json +17 -0
  142. package/vite.config.ts +39 -0
@@ -0,0 +1,419 @@
1
+ import { Container } from 'pixi.js';
2
+ import { Directive, registerDirective } from '../engine/directive';
3
+ import { Element } from '../engine/reactive';
4
+ import { effect, isSignal } from '@signe/reactive';
5
+ import { on, isTrigger, Trigger } from '../engine/trigger';
6
+ import { useProps } from '../hooks/useProps';
7
+ import { SignalOrPrimitive } from '../components/types';
8
+ import { animatedSignal, AnimatedSignal } from '../engine/animation';
9
+ import { Subscription } from 'rxjs';
10
+
11
+ export type FlashType = 'alpha' | 'tint' | 'both';
12
+
13
+ export type FlashProps = {
14
+ /**
15
+ * Trigger that activates the flash animation
16
+ * When the trigger is activated, the flash animation will start
17
+ */
18
+ trigger?: Trigger<any>;
19
+ /**
20
+ * Type of flash effect: 'alpha' (opacity), 'tint' (color), or 'both'
21
+ * @default 'alpha'
22
+ */
23
+ type?: SignalOrPrimitive<FlashType>;
24
+ /**
25
+ * Duration of the flash animation in milliseconds
26
+ * @default 300
27
+ */
28
+ duration?: SignalOrPrimitive<number>;
29
+ /**
30
+ * Number of flash cycles (flash on/off)
31
+ * @default 1
32
+ */
33
+ cycles?: SignalOrPrimitive<number>;
34
+ /**
35
+ * Alpha value when flashing (0 to 1)
36
+ * Only used when type is 'alpha' or 'both'
37
+ * @default 0.3
38
+ */
39
+ alpha?: SignalOrPrimitive<number>;
40
+ /**
41
+ * Tint color when flashing (hex color value)
42
+ * Only used when type is 'tint' or 'both'
43
+ * @default 0xffffff (white)
44
+ */
45
+ tint?: SignalOrPrimitive<number>;
46
+ /**
47
+ * Original alpha value to restore after flash
48
+ * If not provided, uses the current alpha value
49
+ */
50
+ originalAlpha?: number;
51
+ /**
52
+ * Original tint value to restore after flash
53
+ * If not provided, uses the current tint value
54
+ */
55
+ originalTint?: number;
56
+ /**
57
+ * Callback function called when flash starts
58
+ */
59
+ onStart?: () => void;
60
+ /**
61
+ * Callback function called when flash completes
62
+ */
63
+ onComplete?: () => void;
64
+ }
65
+
66
+ /**
67
+ * Flash directive that animates a display object's alpha and/or tint when a trigger is activated.
68
+ * Creates a flash effect by rapidly changing opacity or color.
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * // Basic usage with trigger
73
+ * const flashTrigger = trigger();
74
+ *
75
+ * onMount(element) {
76
+ * // Element will flash when trigger is activated
77
+ * element.props.flash = { trigger: flashTrigger };
78
+ * }
79
+ *
80
+ * // Trigger the flash
81
+ * flashTrigger.start();
82
+ * ```
83
+ */
84
+ export class Flash extends Directive {
85
+ private elementRef: Element<Container> | null = null;
86
+ private progressSignal: AnimatedSignal<number> | null = null;
87
+ private flashSubscription: any = null;
88
+ private alphaEffect: Subscription | null = null;
89
+ private tintEffect: Subscription | null = null;
90
+ private originalAlpha: number = 1;
91
+ private originalTint: number = 0xffffff;
92
+ private currentFlashConfig: {
93
+ type: FlashType;
94
+ duration: number;
95
+ cycles: number;
96
+ flashAlpha: number;
97
+ flashTint: number;
98
+ } | null = null;
99
+
100
+ /**
101
+ * Initializes the flash directive
102
+ * @param element - The element to attach the flash effect to
103
+ */
104
+ onInit(element: Element<Container>) {
105
+ this.elementRef = element;
106
+ }
107
+
108
+ /**
109
+ * Mounts the flash directive and sets up trigger listener
110
+ * @param element - The element being mounted
111
+ */
112
+ onMount(element: Element<Container>) {
113
+ const instance = element.componentInstance;
114
+ if (!instance) return;
115
+
116
+ const flashProps = this.flashProps;
117
+
118
+ // Check if trigger is provided
119
+ if (!flashProps.trigger || !isTrigger(flashProps.trigger)) {
120
+ return;
121
+ }
122
+
123
+ // Store original values once at mount time
124
+ // Only set if not already stored (to preserve values from first mount)
125
+ if (this.originalAlpha === 1 && !flashProps.originalAlpha) {
126
+ this.originalAlpha = instance.alpha ?? 1;
127
+ } else if (flashProps.originalAlpha !== undefined) {
128
+ this.originalAlpha = flashProps.originalAlpha;
129
+ }
130
+
131
+ const currentTint = (instance as any).tint;
132
+ if (this.originalTint === 0xffffff && !flashProps.originalTint) {
133
+ this.originalTint = (isSignal(currentTint) ? currentTint() : currentTint) ?? 0xffffff;
134
+ } else if (flashProps.originalTint !== undefined) {
135
+ this.originalTint = flashProps.originalTint;
136
+ }
137
+
138
+ // Listen to trigger activation
139
+ this.flashSubscription = on(flashProps.trigger, async (data) => {
140
+ await this.performFlash(data);
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Gets the flash props with default values
146
+ * @returns FlashProps with defaults applied
147
+ */
148
+ get flashProps(): FlashProps {
149
+ const flash = this.elementRef?.props.flash;
150
+ return useProps(flash?.value ?? flash, {
151
+ type: 'alpha',
152
+ duration: 300,
153
+ cycles: 1,
154
+ alpha: 0.3,
155
+ tint: 0xffffff,
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Performs the flash animation using animatedSignal
161
+ * @param data - Optional data passed from the trigger that can override default options
162
+ */
163
+ private async performFlash(data?: any): Promise<void> {
164
+ if (!this.elementRef?.componentInstance) return;
165
+
166
+ const instance = this.elementRef.componentInstance;
167
+ const flashProps = this.flashProps;
168
+
169
+ // Use data from trigger to override defaults if provided
170
+ const type = data?.type ?? (typeof flashProps.type === 'function' ? flashProps.type() : flashProps.type);
171
+ const duration = data?.duration ?? (typeof flashProps.duration === 'function' ? flashProps.duration() : flashProps.duration);
172
+ const cycles = data?.cycles ?? (typeof flashProps.cycles === 'function' ? flashProps.cycles() : flashProps.cycles);
173
+ const flashAlpha = data?.alpha ?? (typeof flashProps.alpha === 'function' ? flashProps.alpha() : flashProps.alpha);
174
+ const flashTint = data?.tint ?? (typeof flashProps.tint === 'function' ? flashProps.tint() : flashProps.tint);
175
+
176
+ // Clean up effects BEFORE stopping animation
177
+ // This prevents effects from continuing to update values
178
+ if (this.alphaEffect) {
179
+ this.alphaEffect.unsubscribe();
180
+ this.alphaEffect = null;
181
+ }
182
+ if (this.tintEffect) {
183
+ this.tintEffect.unsubscribe();
184
+ this.tintEffect = null;
185
+ }
186
+
187
+ // DO NOT update original values here if a flash is in progress
188
+ // Only restore to the already-stored original values to avoid overwriting
189
+ // with intermediate animation values when multiple flashes trigger quickly
190
+
191
+ // Always restore to original values immediately after stopping effects
192
+ // This ensures that if a new flash starts before the previous one completes,
193
+ // we restore to the true original values, not the intermediate animation values
194
+ instance.alpha = this.originalAlpha;
195
+ const currentInstanceTint = (instance as any).tint;
196
+ if (currentInstanceTint !== undefined) {
197
+ // Ensure originalTint is a primitive value, not a signal
198
+ const tintValue = typeof this.originalTint === 'number' ? this.originalTint : 0xffffff;
199
+ // Handle both signal and primitive tint
200
+ if (isSignal(currentInstanceTint)) {
201
+ currentInstanceTint.set(tintValue);
202
+ } else {
203
+ (instance as any).tint = tintValue;
204
+ }
205
+ }
206
+
207
+ // Call onStart callback early, before async operations
208
+ flashProps.onStart?.();
209
+
210
+ // Stop any existing animation after cleanup and callback
211
+ if (this.progressSignal) {
212
+ // Stop the animation immediately and wait for completion
213
+ await this.progressSignal.set(0, { duration: 0 });
214
+ }
215
+
216
+ // Store current flash configuration for use in effect
217
+ const flashConfig = {
218
+ type,
219
+ duration,
220
+ cycles,
221
+ flashAlpha,
222
+ flashTint,
223
+ };
224
+ this.currentFlashConfig = flashConfig;
225
+
226
+ // Create or recreate progress signal for flash animation
227
+ // Note: We already stopped the previous animation above, so we can reuse the signal
228
+ if (!this.progressSignal) {
229
+ this.progressSignal = animatedSignal(0, {
230
+ duration: duration,
231
+ ease: (t) => t, // Linear ease
232
+ });
233
+ }
234
+ // Signal is already reset to 0 above if it existed, no need to reset again
235
+
236
+ // Store references to the effects we're creating to verify they're still active later
237
+ const expectedAlphaEffect = type === 'alpha' || type === 'both';
238
+ const expectedTintEffect = type === 'tint' || type === 'both';
239
+
240
+ // Create effect to update alpha based on progress
241
+ if (type === 'alpha' || type === 'both') {
242
+ this.alphaEffect = effect(() => {
243
+ if (!instance || !this.progressSignal || !this.currentFlashConfig) return;
244
+
245
+ const progress = this.progressSignal();
246
+ const config = this.currentFlashConfig;
247
+
248
+ // Calculate flash value based on cycles
249
+ // Each cycle goes from 0 to 1, so we use modulo to repeat
250
+ const cycleProgress = (progress * config.cycles) % 1;
251
+
252
+ // Create flash effect: fade to flashAlpha then back to original
253
+ // For each cycle, we flash twice (on/off)
254
+ const flashPhase = cycleProgress < 0.5
255
+ ? cycleProgress * 2 // Fade to flashAlpha (0 to 1)
256
+ : 1 - ((cycleProgress - 0.5) * 2); // Fade back to original (1 to 0)
257
+
258
+ // Interpolate between original and flash alpha
259
+ const currentAlpha = this.originalAlpha + (config.flashAlpha - this.originalAlpha) * flashPhase;
260
+ instance.alpha = currentAlpha;
261
+ }).subscription;
262
+ }
263
+
264
+ // Create effect to update tint based on progress
265
+ if (type === 'tint' || type === 'both') {
266
+ this.tintEffect = effect(() => {
267
+ if (!instance || !this.progressSignal || !this.currentFlashConfig) return;
268
+
269
+ // Get current tint value - handle both signal and primitive
270
+ const currentTint = (instance as any).tint;
271
+ if (currentTint === undefined) return;
272
+
273
+ // Check if tint is a signal
274
+ const tintIsSignal = isSignal(currentTint);
275
+
276
+ const progress = this.progressSignal();
277
+ const config = this.currentFlashConfig;
278
+
279
+ // Calculate flash value based on cycles
280
+ const cycleProgress = (progress * config.cycles) % 1;
281
+
282
+ // Create flash effect: change to flashTint then back to original
283
+ const flashPhase = cycleProgress < 0.5
284
+ ? cycleProgress * 2 // Change to flashTint (0 to 1)
285
+ : 1 - ((cycleProgress - 0.5) * 2); // Change back to original (1 to 0)
286
+
287
+ // Interpolate between original and flash tint
288
+ // Simple linear interpolation for RGB values
289
+ const r1 = (this.originalTint >> 16) & 0xff;
290
+ const g1 = (this.originalTint >> 8) & 0xff;
291
+ const b1 = this.originalTint & 0xff;
292
+
293
+ const r2 = (config.flashTint >> 16) & 0xff;
294
+ const g2 = (config.flashTint >> 8) & 0xff;
295
+ const b2 = config.flashTint & 0xff;
296
+
297
+ const r = Math.round(r1 + (r2 - r1) * flashPhase);
298
+ const g = Math.round(g1 + (g2 - g1) * flashPhase);
299
+ const b = Math.round(b1 + (b2 - b1) * flashPhase);
300
+
301
+ const newTintValue = (r << 16) | (g << 8) | b;
302
+
303
+ // Handle both signal and primitive tint
304
+ if (tintIsSignal) {
305
+ currentTint.set(newTintValue);
306
+ } else {
307
+ (instance as any).tint = newTintValue;
308
+ }
309
+ }).subscription;
310
+ }
311
+
312
+ // Start animation and wait for completion
313
+ await this.progressSignal.set(1, {
314
+ duration: duration,
315
+ });
316
+
317
+ // Animation completed - clean up and call callbacks
318
+ // Only restore and clean up if this flash is still the active one
319
+ // If currentFlashConfig has changed, it means a new flash has started
320
+ const isStillActive = this.currentFlashConfig === flashConfig;
321
+
322
+ if (isStillActive && instance) {
323
+ // Restore original values
324
+ instance.alpha = this.originalAlpha;
325
+ const currentTint = (instance as any).tint;
326
+ if (currentTint !== undefined) {
327
+ // Ensure originalTint is a primitive value, not a signal
328
+ const tintValue = typeof this.originalTint === 'number' ? this.originalTint : 0xffffff;
329
+ // Handle both signal and primitive tint
330
+ if (isSignal(currentTint)) {
331
+ currentTint.set(tintValue);
332
+ } else {
333
+ (instance as any).tint = tintValue;
334
+ }
335
+ }
336
+
337
+ // Clean up effects
338
+ if (this.alphaEffect) {
339
+ this.alphaEffect.unsubscribe();
340
+ this.alphaEffect = null;
341
+ }
342
+ if (this.tintEffect) {
343
+ this.tintEffect.unsubscribe();
344
+ this.tintEffect = null;
345
+ }
346
+
347
+ // Clear flash config
348
+ this.currentFlashConfig = null;
349
+ }
350
+
351
+ // Call onComplete callback
352
+ flashProps.onComplete?.();
353
+ }
354
+
355
+ /**
356
+ * Updates the flash directive when props change
357
+ * @param props - Updated props
358
+ */
359
+ onUpdate(props: any) {
360
+ // Re-mount if props change significantly
361
+ if (props.type && props.type === 'reset') {
362
+ this.onDestroy();
363
+ if (this.elementRef) {
364
+ this.onMount(this.elementRef);
365
+ }
366
+ }
367
+ }
368
+
369
+ /**
370
+ * Cleans up the flash directive
371
+ */
372
+ onDestroy() {
373
+ // Stop any running animation by resetting progress
374
+ if (this.progressSignal) {
375
+ this.progressSignal.set(0, { duration: 0 });
376
+ this.progressSignal = null;
377
+ }
378
+
379
+ // Clean up effects
380
+ if (this.alphaEffect) {
381
+ this.alphaEffect.unsubscribe();
382
+ this.alphaEffect = null;
383
+ }
384
+ if (this.tintEffect) {
385
+ this.tintEffect.unsubscribe();
386
+ this.tintEffect = null;
387
+ }
388
+
389
+ // Clear flash config
390
+ this.currentFlashConfig = null;
391
+
392
+ // Restore original values
393
+ if (this.elementRef?.componentInstance) {
394
+ const instance = this.elementRef.componentInstance;
395
+ instance.alpha = this.originalAlpha;
396
+ const currentTint = (instance as any).tint;
397
+ if (currentTint !== undefined) {
398
+ // Ensure originalTint is a primitive value, not a signal
399
+ const tintValue = typeof this.originalTint === 'number' ? this.originalTint : 0xffffff;
400
+ // Handle both signal and primitive tint
401
+ if (isSignal(currentTint)) {
402
+ currentTint.set(tintValue);
403
+ } else {
404
+ (instance as any).tint = tintValue;
405
+ }
406
+ }
407
+ }
408
+
409
+ // Clean up subscription
410
+ if (this.flashSubscription) {
411
+ this.flashSubscription = null;
412
+ }
413
+
414
+ this.elementRef = null;
415
+ }
416
+ }
417
+
418
+ registerDirective('flash', Flash);
419
+