@maccesar/titools 2.2.11 → 2.3.0
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.
- package/README.md +255 -713
- package/bin/titools.js +1 -1
- package/lib/commands/update.js +5 -6
- package/lib/config.js +1 -0
- package/lib/downloader.js +10 -0
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +46 -48
- package/skills/alloy-guides/references/CONTROLLERS.md +4 -6
- package/skills/alloy-guides/references/MODELS.md +340 -184
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +3 -4
- package/skills/alloy-guides/references/VIEWS_STYLES.md +44 -46
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +4 -5
- package/skills/alloy-guides/references/VIEWS_XML.md +51 -17
- package/skills/alloy-guides/references/WIDGETS.md +1 -1
- package/skills/alloy-howtos/SKILL.md +12 -13
- package/skills/alloy-howtos/references/cli_reference.md +40 -41
- package/skills/alloy-howtos/references/samples.md +3 -4
- package/skills/purgetss/SKILL.md +369 -356
- package/skills/purgetss/references/EXAMPLES.md +24 -25
- package/skills/purgetss/references/animation-advanced.md +555 -0
- package/skills/purgetss/references/animation-system.md +395 -995
- package/skills/purgetss/references/apply-directive.md +111 -141
- package/skills/purgetss/references/arbitrary-values.md +206 -480
- package/skills/purgetss/references/class-categories.md +277 -0
- package/skills/purgetss/references/class-index.md +1 -420
- package/skills/purgetss/references/cli-commands.md +446 -556
- package/skills/purgetss/references/configurable-properties.md +163 -599
- package/skills/purgetss/references/custom-rules.md +33 -76
- package/skills/purgetss/references/customization-deep-dive.md +319 -518
- package/skills/purgetss/references/dynamic-component-creation.md +33 -37
- package/skills/purgetss/references/grid-layout.md +42 -371
- package/skills/purgetss/references/icon-fonts.md +82 -475
- package/skills/purgetss/references/installation-setup.md +159 -331
- package/skills/purgetss/references/migration-guide.md +54 -109
- package/skills/purgetss/references/opacity-modifier.md +25 -222
- package/skills/purgetss/references/performance-tips.md +2 -2
- package/skills/purgetss/references/platform-modifiers.md +21 -407
- package/skills/purgetss/references/tikit-components.md +237 -104
- package/skills/purgetss/references/titanium-resets.md +20 -21
- package/skills/purgetss/references/ui-ux-design.md +171 -1702
- package/skills/ti-api/SKILL.md +109 -0
- package/skills/ti-api/references/api-android.md +675 -0
- package/skills/ti-api/references/api-app-platform.md +636 -0
- package/skills/ti-api/references/api-core.md +764 -0
- package/skills/ti-api/references/api-data-network.md +641 -0
- package/skills/ti-api/references/api-media.md +655 -0
- package/skills/ti-api/references/api-modules-ble-bluetooth.md +657 -0
- package/skills/ti-api/references/api-modules-coremotion-urlsession.md +411 -0
- package/skills/ti-api/references/api-modules-map.md +632 -0
- package/skills/ti-api/references/api-modules-nfc.md +725 -0
- package/skills/ti-api/references/api-modules-social-misc.md +526 -0
- package/skills/ti-api/references/api-services.md +700 -0
- package/skills/ti-api/references/api-ui-android.md +499 -0
- package/skills/ti-api/references/api-ui-extras.md +702 -0
- package/skills/ti-api/references/api-ui-ios-animator.md +378 -0
- package/skills/ti-api/references/api-ui-ios.md +756 -0
- package/skills/ti-api/references/api-ui-lists.md +581 -0
- package/skills/ti-api/references/api-ui-text-input.md +607 -0
- package/skills/ti-api/references/api-ui-views.md +572 -0
- package/skills/ti-api/references/api-ui-windows-navigation.md +676 -0
- package/skills/ti-api/references/api-xml-global.md +743 -0
- package/skills/ti-expert/SKILL.md +106 -138
- package/skills/ti-expert/references/adaptive-layouts.md +414 -0
- package/skills/ti-expert/references/alloy-builtins.md +16 -20
- package/skills/ti-expert/references/alloy-structure.md +40 -42
- package/skills/ti-expert/references/anti-patterns.md +34 -0
- package/skills/ti-expert/references/architecture-tiers.md +248 -0
- package/skills/ti-expert/references/code-conventions.md +5 -3
- package/skills/ti-expert/references/error-handling.md +14 -7
- package/skills/ti-expert/references/examples.md +4 -2
- package/skills/ti-expert/references/performance-optimization.md +26 -24
- package/skills/ti-expert/references/security-device.md +17 -14
- package/skills/ti-expert/references/security-fundamentals.md +60 -101
- package/skills/ti-expert/references/state-management.md +15 -14
- package/skills/ti-expert/references/testing-e2e-ci.md +30 -21
- package/skills/ti-expert/references/theming.md +12 -20
- package/skills/ti-guides/SKILL.md +13 -17
- package/skills/ti-guides/references/advanced-data-and-images.md +30 -10
- package/skills/ti-guides/references/application-frameworks.md +3 -3
- package/skills/ti-guides/references/coding-best-practices.md +31 -2
- package/skills/ti-guides/references/commonjs-advanced.md +46 -4
- package/skills/ti-guides/references/hello-world.md +9 -13
- package/skills/ti-guides/references/hyperloop-native-access.md +4 -1
- package/skills/ti-guides/references/javascript-primer.md +13 -5
- package/skills/ti-guides/references/resources.md +0 -2
- package/skills/ti-guides/references/style-and-conventions.md +1 -0
- package/skills/ti-guides/references/tiapp-config.md +0 -32
- package/skills/ti-howtos/SKILL.md +43 -45
- package/skills/ti-howtos/references/buffer-codec-streams.md +25 -3
- package/skills/ti-howtos/references/debugging-profiling.md +14 -25
- package/skills/ti-howtos/references/google-maps-v2.md +3 -3
- package/skills/ti-howtos/references/ios-map-kit.md +8 -1
- package/skills/ti-howtos/references/notification-services.md +0 -1
- package/skills/ti-howtos/references/webpack-build-pipeline.md +3 -0
- package/skills/ti-ui/SKILL.md +47 -49
- package/skills/ti-ui/references/application-structures.md +3 -2
- package/skills/ti-ui/references/orientation.md +17 -9
- package/skills/ti-ui/references/platform-ui-ios.md +63 -0
- package/skills/ti-ui/references/scrolling-views.md +39 -0
|
@@ -1,1227 +1,627 @@
|
|
|
1
1
|
# PurgeTSS Animation System
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Introduction
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
**PurgeTSS** includes an Animation module to apply simple 2D Matrix animations and transformations to any element, an array of elements, or even to individual children of an element.
|
|
7
|
-
:::
|
|
5
|
+
PurgeTSS includes an Animation module for 2D Matrix animations and transformations. It works on single elements, arrays of elements, or individual children of an element.
|
|
8
6
|
|
|
9
|
-
The Animation object describes
|
|
7
|
+
The Animation object describes an animation in a few ways:
|
|
10
8
|
- A single-phase animation with an end state
|
|
11
9
|
- A multi-phase animation using the `open`, `close`, and `complete` modifiers
|
|
12
10
|
- Global states for children of a View using the `children` modifier
|
|
13
11
|
|
|
14
|
-
When
|
|
12
|
+
When you call `play` on a View, it animates from its current state to the state described by the Animation object. You can animate position, size, colors, transformation matrix, and opacity. Control timing with classes like `duration-*` and `delay-*`.
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
### Installation
|
|
17
15
|
|
|
18
16
|
```bash
|
|
19
17
|
purgetss module
|
|
20
|
-
#
|
|
18
|
+
# alias:
|
|
21
19
|
purgetss m
|
|
22
20
|
```
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## Basic Usage
|
|
22
|
+
### Usage
|
|
27
23
|
|
|
28
24
|
```xml
|
|
29
|
-
<Animation id="myAnimation" module="purgetss.ui" class="
|
|
25
|
+
<Animation id="myAnimation" module="purgetss.ui" class="a-set-of-purgetss-classes-and-modifiers" />
|
|
30
26
|
```
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
$.myAnimation.play($.myView)
|
|
34
|
-
```
|
|
28
|
+
You can use any position, size, color, transformation, and opacity classes from `utilities.tss`.
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Methods Reference (All 15)
|
|
33
|
+
|
|
34
|
+
| Method | Signature | Description |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| `play` | `play(views, cb)` | Animate views to Animation object state; toggles open/close on repeated calls |
|
|
37
|
+
| `toggle` | `toggle(views, cb)` | Alias for `play`; toggles between open and close states |
|
|
38
|
+
| `apply` | `apply(views, cb)` | Apply properties instantly without animation |
|
|
39
|
+
| `open` | `open(views, cb)` | Explicitly run the opening animation (no toggle) |
|
|
40
|
+
| `close` | `close(views, cb)` | Explicitly run the closing animation (no toggle) |
|
|
41
|
+
| `draggable` | `draggable(views)` | Make views draggable via touch events |
|
|
42
|
+
| `undraggable` | `undraggable(views)` | Remove draggable behavior and clean up all listeners |
|
|
43
|
+
| `detectCollisions` | `detectCollisions(views, dragCB, dropCB)` | Enable collision detection with hover/drop callbacks |
|
|
44
|
+
| `sequence` | `sequence(views, cb)` | Animate views one after another (sequential, not parallel) |
|
|
45
|
+
| `swap` | `swap(view1, view2)` | Animate two views exchanging positions |
|
|
46
|
+
| `pulse` | `pulse(view, count)` | Scale-up-and-back animation (default count=1) |
|
|
47
|
+
| `shake` | `shake(view, intensity)` | Horizontal shake for feedback (default intensity=10) |
|
|
48
|
+
| `snapTo` | `snapTo(view, targets)` | Snap view to nearest target by center distance; returns matched target or null |
|
|
49
|
+
| `reorder` | `reorder(views, newOrder)` | Animate views to new positions by index mapping |
|
|
50
|
+
| `transition` | `transition(views, layouts)` | Multi-view layout transitions using Matrix2D (translate, rotate, scale) |
|
|
51
|
+
|
|
52
|
+
The `play`, `toggle`, `open`, `close`, `apply`, and `sequence` methods accept an optional callback with an enriched event object.
|
|
37
53
|
|
|
38
54
|
---
|
|
39
55
|
|
|
40
|
-
##
|
|
56
|
+
## Modifiers
|
|
41
57
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
58
|
+
| Modifier | Purpose |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `open:` | Properties applied during open state |
|
|
61
|
+
| `close:` | Properties applied during close state |
|
|
62
|
+
| `complete:` | Additional properties applied after an open animation finishes |
|
|
63
|
+
| `children:` | Global properties for all children of a View |
|
|
64
|
+
| `child:` | Individual properties for specific children |
|
|
65
|
+
| `bounds:` | Drag boundaries within parent |
|
|
66
|
+
| `drag:` | Properties applied while dragging |
|
|
67
|
+
| `drop:` | Properties applied on drop |
|
|
48
68
|
|
|
49
|
-
|
|
69
|
+
### Timing and Special Classes
|
|
50
70
|
|
|
51
|
-
|
|
71
|
+
`delay-*`, `duration-*`, `rotate-*`, `scale-*`, `repeat-*`, `zoom-in-*`, `zoom-out-*`, `drag-apply`, `drag-animate`, `ease-in`, `ease-out`, `ease-linear`, `ease-in-out`, `vertical-constraint`, `horizontal-constraint`.
|
|
52
72
|
|
|
53
|
-
|
|
73
|
+
---
|
|
54
74
|
|
|
55
|
-
|
|
75
|
+
## The `play` Method
|
|
56
76
|
|
|
57
|
-
|
|
77
|
+
Runs the animation for a single view or an array of views. Toggles between open and close states on repeated calls.
|
|
58
78
|
|
|
59
79
|
```javascript
|
|
60
80
|
$.myAnimation.play($.myView)
|
|
61
|
-
$.myAnimation.play([$.view1, $.view2])
|
|
62
|
-
$.myAnimation.play($.myView, () => { console.log('done') })
|
|
63
81
|
```
|
|
64
82
|
|
|
65
|
-
|
|
66
|
-
- One-time animations
|
|
67
|
-
- Sequences with callbacks
|
|
68
|
-
- Animating multiple views simultaneously
|
|
69
|
-
|
|
70
|
-
### Play Example 1
|
|
71
|
-
|
|
72
|
-
Create an Animation element and the view you want to animate, and set the desired properties.
|
|
83
|
+
### Basic Example
|
|
73
84
|
|
|
74
|
-
```xml
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
<Animation module="purgetss.ui" id="myAnimation" class="wh-32 bg-green-500 duration-1000" />
|
|
78
|
-
|
|
79
|
-
<View id="square" class="wh-16 bg-blue-500" />
|
|
80
|
-
</Window>
|
|
81
|
-
</Alloy>
|
|
85
|
+
```xml
|
|
86
|
+
<Animation module="purgetss.ui" id="myAnimation" class="wh-32 bg-green-500 duration-1000" />
|
|
87
|
+
<View id="square" class="wh-16 bg-blue-500" />
|
|
82
88
|
```
|
|
83
89
|
|
|
84
|
-
```javascript
|
|
85
|
-
$.index.open()
|
|
86
|
-
|
|
90
|
+
```javascript
|
|
87
91
|
$.myAnimation.play($.square)
|
|
92
|
+
// Blue square animates from 64x64 to 128x128 and changes to green
|
|
88
93
|
```
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
### Play Example 2: Complex Animations with States
|
|
93
|
-
|
|
94
|
-
```xml title="index.xml"
|
|
95
|
-
<Alloy>
|
|
96
|
-
<Window class="keep-screen-on">
|
|
97
|
-
<Animation id="changeWidth" class="close:w-28 debug open:w-11/12" module="purgetss.ui" />
|
|
98
|
-
<Animation id="changeColor" class="close:bg-blue-700 debug open:bg-purple-500" module="purgetss.ui" />
|
|
99
|
-
<Animation id="changeTransparency" class="close:duration-300 open:mt-(null) close:mt-8 open:h-11/12 close:w-14 close:h-14 close:opacity-100 open:w-10/12 open:opacity-50 open:duration-150" module="purgetss.ui" />
|
|
100
|
-
<Animation id="changeRetweet" class="close:duration-150 close:-mb-52 open:-mb-16 open:duration-200" module="purgetss.ui" />
|
|
101
|
-
|
|
102
|
-
<View class="vertical">
|
|
103
|
-
<Button class="ios:mt-16 mt-1 w-48 rounded bg-purple-500 text-purple-50" onClick="squaresFn" title="3 Squares" />
|
|
104
|
-
<Button class="mt-2 w-48 rounded bg-purple-500 text-purple-50" onClick="toggleFn" title="Toggle Colors" />
|
|
105
|
-
<Button class="mt-2 w-48 rounded bg-purple-500 text-purple-50" onClick="retweetFn" title="Toggle Re-Tweet" />
|
|
106
|
-
|
|
107
|
-
<View id="squaresView" class="vertical mt-10 w-screen">
|
|
108
|
-
<View class="wh-28 rounded-xl bg-blue-700" />
|
|
109
|
-
<View class="wh-28 mt-4 rounded-xl bg-blue-700" />
|
|
110
|
-
<View class="wh-28 mt-4 rounded-xl bg-blue-700" />
|
|
111
|
-
</View>
|
|
112
|
-
</View>
|
|
113
|
-
|
|
114
|
-
<View id="blueSquareView" class="mt-8 h-14 w-14 rounded-xl bg-blue-500" onClick="transparencyFn" />
|
|
115
|
-
|
|
116
|
-
<View id="retweetView" class="vertical -mb-52 h-48 w-screen rounded-2xl bg-gray-800" onClick="retweetFn">
|
|
117
|
-
<View class="mt-4 h-1 w-8 bg-slate-700" />
|
|
118
|
-
|
|
119
|
-
<View class="horizontal mx-4 mt-4">
|
|
120
|
-
<Label class="fas fa-retweet w-7 text-xl text-slate-500" />
|
|
121
|
-
<Label class="ml-2 text-left text-xl text-white" text="Re-Tweet" />
|
|
122
|
-
</View>
|
|
123
|
-
|
|
124
|
-
<View class="horizontal mx-4 mt-4">
|
|
125
|
-
<Label class="fas fa-pencil-alt w-7 text-xl text-slate-500" />
|
|
126
|
-
<Label class="ml-2 text-left text-xl text-white" text="Quote Tweet" />
|
|
127
|
-
</View>
|
|
128
|
-
</View>
|
|
129
|
-
</Window>
|
|
130
|
-
</Alloy>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
```javascript title="index.js"
|
|
134
|
-
function transparencyFn() {
|
|
135
|
-
$.changeTransparency.play($.blueSquareView)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function toggleFn() {
|
|
139
|
-
$.changeColor.toggle($.squaresView.children)
|
|
140
|
-
}
|
|
95
|
+
### open/close Modifiers
|
|
141
96
|
|
|
142
|
-
|
|
143
|
-
$.changeWidth.play($.squaresView.children)
|
|
144
|
-
}
|
|
97
|
+
Define different states for opening and closing:
|
|
145
98
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
$.index.open()
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### `toggle(views, [callback])`
|
|
154
|
-
|
|
155
|
-
Alternates between `open:` and `close:` states.
|
|
156
|
-
|
|
157
|
-
```javascript
|
|
158
|
-
$.myAnimation.toggle($.myView)
|
|
99
|
+
```xml
|
|
100
|
+
<Animation id="changeColor" module="purgetss.ui" class="close:bg-blue-700 open:bg-purple-500" />
|
|
159
101
|
```
|
|
160
102
|
|
|
161
|
-
|
|
162
|
-
- UI state toggles (show/hide)
|
|
163
|
-
- Accordion behavior
|
|
164
|
-
- Alternating animations
|
|
165
|
-
|
|
166
|
-
---
|
|
103
|
+
First call applies `open:` properties; next call applies `close:` properties; continues toggling.
|
|
167
104
|
|
|
168
|
-
|
|
105
|
+
### `complete` Modifier
|
|
169
106
|
|
|
170
|
-
|
|
107
|
+
Applies additional properties after an `open` animation finishes:
|
|
171
108
|
|
|
172
|
-
|
|
109
|
+
```xml
|
|
110
|
+
<Animation module="purgetss.ui" id="myAnimationOpen"
|
|
111
|
+
class="open:scale-1 complete:bg-(#008800) complete:scale-100" />
|
|
112
|
+
```
|
|
173
113
|
|
|
174
|
-
|
|
114
|
+
View scales to `scale-1` (open), then on completion receives `bg-(#008800)` and `scale-100`.
|
|
175
115
|
|
|
176
|
-
###
|
|
116
|
+
### Animating Arrays
|
|
177
117
|
|
|
178
|
-
|
|
118
|
+
Pass an array or `.children` to animate all views:
|
|
179
119
|
|
|
180
120
|
```javascript
|
|
181
|
-
$.myAnimation.
|
|
121
|
+
$.myAnimation.play($.squaresView.children)
|
|
122
|
+
$.myAnimation.play([$.view1, $.view2, $.view3])
|
|
182
123
|
```
|
|
183
124
|
|
|
184
|
-
|
|
185
|
-
- `callback`: An optional callback function that gets called when the animation completes.
|
|
186
|
-
|
|
187
|
-
#### Open Method Example
|
|
188
|
-
|
|
189
|
-
```xml title="index.xml"
|
|
190
|
-
<Alloy>
|
|
191
|
-
<Window>
|
|
192
|
-
<Animation module="purgetss.ui" id="myAnimation" class="close:opacity-0 open:opacity-100" />
|
|
125
|
+
The callback fires once per view. Use `e.index` and `e.total` to track progress.
|
|
193
126
|
|
|
194
|
-
|
|
195
|
-
</Window>
|
|
196
|
-
</Alloy>
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
```javascript title="index.js"
|
|
200
|
-
$.myAnimation.open($.myView, () => {
|
|
201
|
-
console.log('Open animation complete');
|
|
202
|
-
});
|
|
203
|
-
```
|
|
127
|
+
---
|
|
204
128
|
|
|
205
|
-
|
|
129
|
+
## Callback Event Object
|
|
206
130
|
|
|
207
|
-
|
|
131
|
+
All methods that accept a callback (`play`, `toggle`, `open`, `close`, `apply`, `sequence`) receive an enriched event object:
|
|
208
132
|
|
|
209
|
-
|
|
133
|
+
```javascript
|
|
134
|
+
$.myAnimation.play($.myView, (e) => {
|
|
135
|
+
console.log(e.action) // 'play'
|
|
136
|
+
console.log(e.state) // 'open' or 'close'
|
|
137
|
+
console.log(e.id) // Animation object ID
|
|
138
|
+
console.log(e.targetId) // ID of the animated view
|
|
139
|
+
})
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Event Object Properties
|
|
143
|
+
|
|
144
|
+
| Property | Type | Description |
|
|
145
|
+
| --- | --- | --- |
|
|
146
|
+
| `type` | `String` | `'complete'` (for play/open/close) or `'applied'` (for apply) |
|
|
147
|
+
| `bubbles` | `Boolean` | Whether the event bubbles |
|
|
148
|
+
| `cancelBubble` | `Boolean` | Whether bubbling is cancelled |
|
|
149
|
+
| `action` | `String` | `'play'` or `'apply'` |
|
|
150
|
+
| `state` | `String` | `'open'` or `'close'` |
|
|
151
|
+
| `id` | `String` | ID of the Animation object |
|
|
152
|
+
| `targetId` | `String` | ID of the animated view |
|
|
153
|
+
| `index` | `Number` | Position of the view in the array (0-based) |
|
|
154
|
+
| `total` | `Number` | Total number of views in the array |
|
|
155
|
+
| `getTarget()` | `Function` | Returns the animated view object |
|
|
156
|
+
|
|
157
|
+
### Tracking Array Progress
|
|
210
158
|
|
|
211
159
|
```javascript
|
|
212
|
-
$.myAnimation.
|
|
160
|
+
$.myAnimation.play([$.card1, $.card2, $.card3], (e) => {
|
|
161
|
+
console.log(`Animated ${e.index + 1} of ${e.total}`)
|
|
162
|
+
if (e.index === e.total - 1) console.log('All animations complete')
|
|
163
|
+
})
|
|
213
164
|
```
|
|
214
165
|
|
|
215
|
-
|
|
216
|
-
- `callback`: An optional callback function that gets called when the animation completes.
|
|
217
|
-
|
|
218
|
-
#### Close Method Example
|
|
219
|
-
|
|
220
|
-
```xml title="index.xml"
|
|
221
|
-
<Alloy>
|
|
222
|
-
<Window>
|
|
223
|
-
<Animation module="purgetss.ui" id="myAnimation" class="close:opacity-0 open:opacity-100" />
|
|
224
|
-
|
|
225
|
-
<View id="myView" class="opacity-100" />
|
|
226
|
-
</Window>
|
|
227
|
-
</Alloy>
|
|
228
|
-
```
|
|
166
|
+
Use `getTarget()` to reference the specific view that just finished:
|
|
229
167
|
|
|
230
|
-
```javascript
|
|
231
|
-
$.myAnimation.
|
|
232
|
-
|
|
233
|
-
})
|
|
168
|
+
```javascript
|
|
169
|
+
$.myAnimation.play([$.card1, $.card2, $.card3], (e) => {
|
|
170
|
+
e.getTarget().borderColor = 'green'
|
|
171
|
+
})
|
|
234
172
|
```
|
|
235
173
|
|
|
236
|
-
In this example, the `myView` element will apply the animation properties defined in the classes with the `close` modifier when the `close` method is called, making the view fully transparent.
|
|
237
|
-
|
|
238
|
-
:::info
|
|
239
|
-
The `open` and `close` methods provide explicit control over animation states, as opposed to `play` or `toggle` which alternate based on current state.
|
|
240
|
-
:::
|
|
241
|
-
|
|
242
174
|
---
|
|
243
175
|
|
|
244
176
|
## The `apply` Method
|
|
245
177
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
### `apply(views)`
|
|
249
|
-
|
|
250
|
-
Applies properties instantly without animation (bypasses bridge thread).
|
|
178
|
+
Applies properties instantly without animation. Callback has `action='apply'` and `type='applied'`.
|
|
251
179
|
|
|
252
180
|
```javascript
|
|
253
181
|
$.myAnimation.apply($.myView)
|
|
254
|
-
```
|
|
255
182
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
### Apply Example: TikTok-like Interface
|
|
262
|
-
|
|
263
|
-
The `apply` method sets the properties instantly. In this example, the `ScrollableView` is rotated 90 degrees, and its content is counter-rotated -90 degrees to simulate a **TikTok-like** interface.
|
|
264
|
-
|
|
265
|
-
```xml title="index.xml"
|
|
266
|
-
<Alloy>
|
|
267
|
-
<Window class="exit-on-close-false keep-screen-on">
|
|
268
|
-
<Animation module="purgetss.ui" id="rotate" class="platform-wh-inverted rotate-90" />
|
|
269
|
-
<Animation module="purgetss.ui" id="counterRotate" class="platform-wh -rotate-90" />
|
|
270
|
-
|
|
271
|
-
<ScrollableView id="scrollableView" class="overlay-enabled disable-bounce paging-control-alpha-100 scrolling-enabled show-paging-control paging-control-h-14 paging-control-on-top-false paging-control-transparent page-indicator-(rgba(0,0,0,0.24)) current-page-indicator-(rgba(0,0,0,1))">
|
|
272
|
-
<View class="bg-blue-500">
|
|
273
|
-
<Label class="text-center" text="View's Content" />
|
|
274
|
-
</View>
|
|
183
|
+
$.myAnimation.apply($.myView, (e) => {
|
|
184
|
+
console.log(e.action) // 'apply'
|
|
185
|
+
console.log(e.state) // 'open' or 'close'
|
|
186
|
+
})
|
|
187
|
+
```
|
|
275
188
|
|
|
276
|
-
|
|
277
|
-
<Label class="text-center" text="View's Content" />
|
|
278
|
-
</View>
|
|
189
|
+
### TikTok-Style Rotation Example
|
|
279
190
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
191
|
+
```xml
|
|
192
|
+
<Animation module="purgetss.ui" id="rotate" class="platform-wh-inverted rotate-90" />
|
|
193
|
+
<Animation module="purgetss.ui" id="counterRotate" class="platform-wh -rotate-90" />
|
|
194
|
+
<ScrollableView id="scrollableView" class="overlay-enabled disable-bounce">
|
|
195
|
+
<View class="bg-blue-500"><Label text="Page 1" /></View>
|
|
196
|
+
<View class="bg-red-500"><Label text="Page 2" /></View>
|
|
197
|
+
</ScrollableView>
|
|
286
198
|
```
|
|
287
199
|
|
|
288
|
-
```javascript
|
|
200
|
+
```javascript
|
|
289
201
|
$.rotate.apply($.scrollableView)
|
|
290
|
-
|
|
291
202
|
$.counterRotate.apply($.scrollableView.views)
|
|
292
|
-
|
|
293
203
|
$.index.open()
|
|
294
204
|
```
|
|
295
205
|
|
|
296
206
|
---
|
|
297
207
|
|
|
298
|
-
## The `
|
|
299
|
-
|
|
300
|
-
The `draggable` method allows you to convert any view or an array of views into draggable elements.
|
|
208
|
+
## The `open` and `close` Methods
|
|
301
209
|
|
|
302
|
-
|
|
303
|
-
- You can `apply` or `animate` the properties either globally or locally using the `drag-apply` or `drag-animate` classes.
|
|
304
|
-
- You can also constrain any view using the `horizontal-constraint` or `vertical-constraint` classes.
|
|
210
|
+
Run opening and closing animations explicitly. They do not toggle -- you get direct control.
|
|
305
211
|
|
|
306
212
|
```javascript
|
|
307
|
-
|
|
308
|
-
$.
|
|
213
|
+
$.myAnimation.open(views, callback)
|
|
214
|
+
$.myAnimation.close(views, callback)
|
|
309
215
|
```
|
|
310
216
|
|
|
311
|
-
|
|
312
|
-
**You can create a blank `Animation` object or use an existing one to call the `draggable` method to convert a view or array of views into 'draggable' objects.**
|
|
217
|
+
`open` uses properties under the `open:` modifier; `close` uses `close:` modifier. The callback receives the same enriched event object as `play`.
|
|
313
218
|
|
|
314
|
-
|
|
315
|
-
:::
|
|
219
|
+
### Panel with Zoom-In Effect
|
|
316
220
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
<
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
<Label text="Draggable Example" class="mt-16 text-center" />
|
|
325
|
-
|
|
326
|
-
<View id="red" class="ml-4 h-32 w-32 rounded-lg bg-red-500" />
|
|
327
|
-
|
|
328
|
-
<View id="green" class="ml-10 h-32 w-32 rounded-lg bg-green-500" />
|
|
329
|
-
|
|
330
|
-
<View id="blue" class="ml-16 h-32 w-32 rounded-lg bg-blue-500" />
|
|
331
|
-
</Window>
|
|
332
|
-
</Alloy>
|
|
221
|
+
```xml
|
|
222
|
+
<View id="panel" class="hidden opacity-0" onClick="onOverlayTap">
|
|
223
|
+
<View class="h-screen w-screen bg-(#80000000)" />
|
|
224
|
+
<View id="content" class="zoom-in-110 close:duration-0 open:duration-100 mx-6 rounded-xl bg-slate-800" />
|
|
225
|
+
</View>
|
|
226
|
+
<Animation id="panelAnim" module="purgetss.ui" class="opacity-to-100 duration-75 ease-out" />
|
|
333
227
|
```
|
|
334
228
|
|
|
335
|
-
```javascript
|
|
336
|
-
|
|
229
|
+
```javascript
|
|
230
|
+
function showPanel() {
|
|
231
|
+
$.panel.show()
|
|
232
|
+
$.panelAnim.open($.panel)
|
|
233
|
+
}
|
|
337
234
|
|
|
338
|
-
|
|
235
|
+
function closePanel() {
|
|
236
|
+
$.panelAnim.close($.panel, () => { $.panel.hide() })
|
|
237
|
+
}
|
|
339
238
|
```
|
|
340
239
|
|
|
341
|
-
|
|
240
|
+
Key classes: `zoom-in-110` (pop effect), `opacity-to-100` (fade overlay), `close:duration-0 open:duration-100` (instant close, animated open).
|
|
342
241
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
- You can set 'global' modifiers in the `Animation` object, or you can set individual modifiers for each view.
|
|
346
|
-
- Local modifiers will overwrite any global modifier.
|
|
347
|
-
|
|
348
|
-
:::info
|
|
349
|
-
To simplify things, we are restricting the types of animations that can be applied while dragging (or dropping).
|
|
242
|
+
---
|
|
350
243
|
|
|
351
|
-
|
|
352
|
-
:::
|
|
244
|
+
## The `draggable` Method
|
|
353
245
|
|
|
354
|
-
|
|
246
|
+
Makes one or more views draggable.
|
|
355
247
|
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
<!-- Global set of modifiers -->
|
|
360
|
-
<Animation id="draggableAnimation" module="purgetss.ui" class="drag:duration-100 drag:opacity-50 drop:opacity-100" />
|
|
248
|
+
```javascript
|
|
249
|
+
$.draggableAnimation.draggable([$.red, $.green, $.blue])
|
|
250
|
+
```
|
|
361
251
|
|
|
362
|
-
|
|
252
|
+
A blank or existing Animation object can be reused. When used with an array, zIndex is managed automatically.
|
|
363
253
|
|
|
364
|
-
|
|
365
|
-
<Label id="red" class="mx-2 ml-4 h-32 w-32 rounded-lg bg-red-500 text-center text-xs text-white" text="No local modifiers" />
|
|
254
|
+
### `drag:` and `drop:` Modifiers
|
|
366
255
|
|
|
367
|
-
|
|
368
|
-
|
|
256
|
+
- **Global modifiers** on the Animation object apply to all views
|
|
257
|
+
- **Local modifiers** on individual views override globals
|
|
258
|
+
- While dragging, `size`, `scale`, and `anchorPoint` transformations are **not** applied
|
|
369
259
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
</Alloy>
|
|
260
|
+
```xml
|
|
261
|
+
<Animation id="draggableAnimation" module="purgetss.ui" class="drag:duration-100 drag:opacity-50 drop:opacity-100" />
|
|
262
|
+
<Label id="green" class="drag:bg-green-800 drop:bg-green-500 ml-10 h-32 w-32 rounded-lg bg-green-500" />
|
|
374
263
|
```
|
|
375
264
|
|
|
376
265
|
### `draggingType` Property
|
|
377
266
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
/* Property(ies): draggingType */
|
|
383
|
-
.drag-apply { draggingType: 'apply' }
|
|
384
|
-
.drag-animate { draggingType: 'animate' }
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
#### Dragging Type Example
|
|
388
|
-
|
|
389
|
-
In the following example, the `Animation` element sets the global dragging type to `drag-apply`, but the green square overwrites it to `drag-animate`.
|
|
267
|
+
| Class | Behavior |
|
|
268
|
+
| --- | --- |
|
|
269
|
+
| `drag-animate` | Animate properties (default) |
|
|
270
|
+
| `drag-apply` | Apply properties instantly |
|
|
390
271
|
|
|
391
|
-
|
|
392
|
-
<Alloy>
|
|
393
|
-
<Window class="keep-screen-on exit-on-close-false">
|
|
394
|
-
<!-- Global set of modifiers -->
|
|
395
|
-
<Animation id="draggableAnimation" module="purgetss.ui" class="drag-apply drag:duration-500 drag:opacity-50 drop:opacity-100" />
|
|
272
|
+
### `bounds:` Modifier
|
|
396
273
|
|
|
397
|
-
|
|
274
|
+
Limits movement within the parent. Local on the view or global on the Animation object (local overrides global):
|
|
398
275
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
<!-- drag-animate drag:bg-green-800 drop:bg-green-500 -->
|
|
403
|
-
<Label id="green" class="drag-animate drag:bg-green-800 drop:bg-green-500 ml-10 h-32 w-32 rounded-lg bg-green-500 text-center text-xs text-white" text="drag-animate drag:bg-green-800 drop:bg-green-500" />
|
|
404
|
-
|
|
405
|
-
<!-- drag:opacity-25 -->
|
|
406
|
-
<Label id="blue" class="drag:opacity-25 ml-16 h-32 w-32 rounded-lg bg-blue-500 text-center text-xs text-white" text="drag:opacity-25" />
|
|
407
|
-
</Window>
|
|
408
|
-
</Alloy>
|
|
276
|
+
```xml
|
|
277
|
+
<View id="card" class="bounds:m-2 bounds:mb-16 mt-8 h-24 w-64" />
|
|
278
|
+
<Animation id="dragAnim" module="purgetss.ui" class="bounds:m-2 bounds:mb-16" />
|
|
409
279
|
```
|
|
410
280
|
|
|
411
|
-
###
|
|
412
|
-
|
|
413
|
-
You can set boundaries in which a view can move within its parent view using the `bounds:` modifier.
|
|
414
|
-
|
|
415
|
-
- You can set global boundaries in the Animation object and/or local boundaries for each individual child view.
|
|
416
|
-
- Local values will overwrite any global values.
|
|
417
|
-
|
|
418
|
-
#### Bounds Example 1: Local Bounds
|
|
281
|
+
### Constraints
|
|
419
282
|
|
|
420
|
-
|
|
283
|
+
| Class | Effect |
|
|
284
|
+
| --- | --- |
|
|
285
|
+
| `horizontal-constraint` | Horizontal movement only |
|
|
286
|
+
| `vertical-constraint` | Vertical movement only |
|
|
421
287
|
|
|
422
|
-
|
|
423
|
-
<Alloy>
|
|
424
|
-
<Window class="keep-screen-on exit-on-close-false bg-green-50">
|
|
425
|
-
<Animation id="draggableAnimation" module="purgetss.ui" />
|
|
426
|
-
|
|
427
|
-
<View class="mx-6 mb-6 mt-10 h-screen w-screen rounded-lg bg-green-200">
|
|
428
|
-
<View id="card" class="bounds:m-2 bounds:mb-16 mt-8 h-24 w-64 shadow-lg">
|
|
429
|
-
<View id="cardInside" class="w-screen rounded-lg border-2 border-purple-700 bg-white">
|
|
430
|
-
<ImageView id="theImage" class="rounded-16 prevent-default-image m-4 ml-4 h-16 w-16 bg-gray-50" image="https://randomuser.me/api/portraits/women/17.jpg" />
|
|
431
|
-
|
|
432
|
-
<View class="vertical ml-24 w-screen">
|
|
433
|
-
<Label class="ml-0 text-sm font-bold text-gray-800" text="Ms. Jane Doe" />
|
|
434
|
-
<Label class="ml-0 text-xs font-bold text-gray-400" text="Website Designer" />
|
|
435
|
-
</View>
|
|
436
|
-
</View>
|
|
437
|
-
</View>
|
|
438
|
-
|
|
439
|
-
<Label class="bg-(#80000000) mx-2 mb-2 h-12 w-screen rounded-lg text-center text-white" text="Some Element..." />
|
|
440
|
-
</View>
|
|
441
|
-
</Window>
|
|
442
|
-
</Alloy>
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
```javascript title="index.js"
|
|
446
|
-
$.index.open()
|
|
447
|
-
|
|
448
|
-
$.draggableAnimation.draggable($.card)
|
|
449
|
-
```
|
|
288
|
+
---
|
|
450
289
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
In this example, the boundaries are set globally in the `draggableAnimation` view. Every card view will use these global values.
|
|
454
|
-
|
|
455
|
-
```xml title="index.xml"
|
|
456
|
-
<Alloy>
|
|
457
|
-
<Window class="keep-screen-on exit-on-close-false bg-green-50">
|
|
458
|
-
<Animation id="draggableAnimation" module="purgetss.ui" class="bounds:m-2 bounds:mb-16" />
|
|
459
|
-
|
|
460
|
-
<View class="wh-screen mx-6 mb-6 mt-10 rounded-lg bg-green-200">
|
|
461
|
-
<View id="card" class="mt-8 h-24 w-64 shadow-lg">
|
|
462
|
-
<View id="cardInside" class="w-screen rounded-lg border-2 border-purple-700 bg-white">
|
|
463
|
-
<ImageView id="theImage" class="rounded-16 prevent-default-image wh-16 m-4 bg-gray-50" image="https://randomuser.me/api/portraits/women/17.jpg" />
|
|
464
|
-
|
|
465
|
-
<View class="vertical ml-24 w-screen">
|
|
466
|
-
<Label class="ml-0 text-sm font-bold text-gray-800" text="Ms. Jane Doe" />
|
|
467
|
-
<Label class="ml-0 text-xs font-bold text-gray-400" text="Website Designer" />
|
|
468
|
-
</View>
|
|
469
|
-
</View>
|
|
470
|
-
</View>
|
|
471
|
-
|
|
472
|
-
<View id="card2" class="mt-40 h-24 w-64 shadow-lg">
|
|
473
|
-
<View id="cardInside" class="w-screen rounded-lg border-2 border-purple-700 bg-white">
|
|
474
|
-
<ImageView id="theImage" class="rounded-16 prevent-default-image wh-16 m-4 bg-gray-50" image="https://randomuser.me/api/portraits/women/21.jpg" />
|
|
475
|
-
|
|
476
|
-
<View class="vertical ml-24 w-screen">
|
|
477
|
-
<Label class="ml-0 text-sm font-bold text-gray-800" text="Ms. Jane Doe" />
|
|
478
|
-
<Label class="ml-0 text-xs font-bold text-gray-400" text="Website Designer" />
|
|
479
|
-
</View>
|
|
480
|
-
</View>
|
|
481
|
-
</View>
|
|
482
|
-
|
|
483
|
-
<View id="card3" class="mt-72 h-24 w-64 shadow-lg">
|
|
484
|
-
<View id="cardInside" class="w-screen rounded-lg border-2 border-purple-700 bg-white">
|
|
485
|
-
<ImageView id="theImage" class="rounded-16 prevent-default-image wh-16 m-4 bg-gray-50" image="https://randomuser.me/api/portraits/women/25.jpg" />
|
|
486
|
-
|
|
487
|
-
<View class="vertical ml-24 w-screen">
|
|
488
|
-
<Label class="ml-0 text-sm font-bold text-gray-800" text="Ms. Jane Doe" />
|
|
489
|
-
<Label class="ml-0 text-xs font-bold text-gray-400" text="Website Designer" />
|
|
490
|
-
</View>
|
|
491
|
-
</View>
|
|
492
|
-
</View>
|
|
493
|
-
|
|
494
|
-
<Label class="bg-(#80000000) mx-2 mb-2 h-12 w-screen rounded-lg text-center text-white" text="Some Element..." />
|
|
495
|
-
</View>
|
|
496
|
-
</Window>
|
|
497
|
-
</Alloy>
|
|
498
|
-
```
|
|
290
|
+
## The `undraggable` Method
|
|
499
291
|
|
|
500
|
-
|
|
501
|
-
$.index.open()
|
|
292
|
+
Removes draggable behavior and cleans up all listeners from one or more views.
|
|
502
293
|
|
|
503
|
-
|
|
294
|
+
```javascript
|
|
295
|
+
$.draggableAnimation.undraggable($.card)
|
|
296
|
+
$.draggableAnimation.undraggable([$.card1, $.card2, $.card3])
|
|
504
297
|
```
|
|
505
298
|
|
|
506
|
-
|
|
299
|
+
Removes: `touchstart`/`touchend`/`touchmove` listeners, `Ti.Gesture.orientationchange` listener, collision detection registry entries, and internal properties (`_originTop`, `_originLeft`, `_visualTop`, `_visualLeft`, `_collisionEnabled`, `_dragListeners`, `_wasDragged`, `_bouncingBack`).
|
|
507
300
|
|
|
508
|
-
|
|
301
|
+
**Use cases:** Lock a piece after correct placement, toggle edit/presentation mode, cleanup on window close (prevents memory leaks from global `orientationchange` listener).
|
|
509
302
|
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
'.vertical-constraint': { constraint: 'vertical' }
|
|
303
|
+
```javascript
|
|
304
|
+
function onClose() {
|
|
305
|
+
$.anim.undraggable(allDraggableViews)
|
|
306
|
+
}
|
|
515
307
|
```
|
|
516
308
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
In this example, the `card` view will move only from side to side.
|
|
520
|
-
|
|
521
|
-
```xml title="index.xml"
|
|
522
|
-
<Alloy>
|
|
523
|
-
<Window class="keep-screen-on exit-on-close-false">
|
|
524
|
-
<Animation id="draggableAnimation" module="purgetss.ui" />
|
|
525
|
-
|
|
526
|
-
<View id="card" class="horizontal-constraint h-24 w-64 shadow-lg">
|
|
527
|
-
<View id="cardInside" class="w-screen rounded-lg border-2 border-purple-700 bg-white">
|
|
528
|
-
<ImageView id="theImage" class="rounded-16 wh-16 m-4 ml-4" image="https://randomuser.me/api/portraits/women/17.jpg" />
|
|
309
|
+
---
|
|
529
310
|
|
|
530
|
-
|
|
531
|
-
<Label class="ml-0 text-sm font-bold text-gray-800" text="Ms. Jane Doe" />
|
|
532
|
-
<Label class="ml-0 text-xs font-bold text-gray-400" text="Website Designer" />
|
|
533
|
-
</View>
|
|
534
|
-
</View>
|
|
535
|
-
</View>
|
|
536
|
-
</Window>
|
|
537
|
-
</Alloy>
|
|
538
|
-
```
|
|
311
|
+
## The `detectCollisions` Method
|
|
539
312
|
|
|
540
|
-
|
|
541
|
-
$.index.open()
|
|
313
|
+
After calling `draggable()`, enable collision detection based on center-point hit testing.
|
|
542
314
|
|
|
543
|
-
|
|
315
|
+
```javascript
|
|
316
|
+
$.myAnimation.draggable(views)
|
|
317
|
+
$.myAnimation.detectCollisions(views, dragCB, dropCB)
|
|
544
318
|
```
|
|
545
319
|
|
|
546
|
-
|
|
320
|
+
### Parameters
|
|
547
321
|
|
|
548
|
-
|
|
322
|
+
| Parameter | Type | Description |
|
|
323
|
+
| --- | --- | --- |
|
|
324
|
+
| `views` | `View/Array` | Views to register for collision detection |
|
|
325
|
+
| `dragCB` | `Function(source, target)` | Called during drag; `target` is the view under the drag center, or `null` when leaving |
|
|
326
|
+
| `dropCB` | `Function(source, target)` | Called on drop when a collision target is found |
|
|
549
327
|
|
|
550
|
-
|
|
328
|
+
### Snap Classes
|
|
551
329
|
|
|
552
|
-
|
|
330
|
+
Off by default -- opt-in via classes on the `<Animation>` object:
|
|
553
331
|
|
|
554
|
-
|
|
332
|
+
| Class | Behavior |
|
|
333
|
+
| --- | --- |
|
|
334
|
+
| `snap-back` | View returns to origin when dropped **outside** any target |
|
|
335
|
+
| `snap-center` | View auto-centers on target when dropped **on** it (uses `snapTo` internally) |
|
|
555
336
|
|
|
556
337
|
```xml
|
|
557
|
-
<Animation class="
|
|
338
|
+
<Animation id="myAnim" module="purgetss.ui" class="snap-back snap-center duration-200" />
|
|
558
339
|
```
|
|
559
340
|
|
|
560
|
-
###
|
|
341
|
+
### Example
|
|
561
342
|
|
|
562
|
-
|
|
343
|
+
```javascript
|
|
344
|
+
const views = [$.dropZone, $.card]
|
|
345
|
+
$.myAnimation.draggable(views)
|
|
346
|
+
$.myAnimation.detectCollisions(views,
|
|
347
|
+
(source, target) => {
|
|
348
|
+
if (target) {
|
|
349
|
+
target.borderColor = 'green'
|
|
350
|
+
} else {
|
|
351
|
+
$.dropZone.borderColor = '#9ca3af'
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
(source, target) => {
|
|
355
|
+
console.log(`Dropped ${source.id} onto ${target.id}`)
|
|
356
|
+
}
|
|
357
|
+
)
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Drag-to-Swap Grid
|
|
361
|
+
|
|
362
|
+
Combining `draggable` + `detectCollisions` + `swap`:
|
|
563
363
|
|
|
564
|
-
```
|
|
565
|
-
|
|
364
|
+
```javascript
|
|
365
|
+
const cards = [$.c0, $.c1, $.c2, $.c3]
|
|
366
|
+
$.gridAnim.draggable(cards)
|
|
367
|
+
|
|
368
|
+
let lastTarget = null
|
|
369
|
+
$.gridAnim.detectCollisions(cards,
|
|
370
|
+
(source, target) => {
|
|
371
|
+
if (lastTarget && lastTarget !== target) lastTarget.applyProperties({ opacity: 1 })
|
|
372
|
+
if (target) target.applyProperties({ opacity: 0.6 })
|
|
373
|
+
lastTarget = target
|
|
374
|
+
},
|
|
375
|
+
(source, target) => {
|
|
376
|
+
if (target) {
|
|
377
|
+
target.applyProperties({ opacity: 1 })
|
|
378
|
+
$.gridAnim.swap(source, target)
|
|
379
|
+
}
|
|
380
|
+
lastTarget = null
|
|
381
|
+
}
|
|
382
|
+
)
|
|
566
383
|
```
|
|
567
384
|
|
|
568
|
-
|
|
569
|
-
Use `complete:` for post-animation state - e.g., setting a background color after a fade-in completes.
|
|
570
|
-
:::
|
|
571
|
-
|
|
572
|
-
#### Complete Example: Wordle Animation
|
|
573
|
-
|
|
574
|
-
In the following code, the `open` animation reduces the children of the `letters` view to a size of 1%. After completion, the `complete` modifier will set the background color to green and the scaling back to 100%.
|
|
575
|
-
|
|
576
|
-
```xml title="index.xml"
|
|
577
|
-
<Alloy>
|
|
578
|
-
<Window title="App Wordle" class="bg-(#181e2d)">
|
|
579
|
-
<Animation module="purgetss.ui" id="myAnimationReset" class="bg-transparent" />
|
|
580
|
-
<Animation module="purgetss.ui" id="myAnimationOpen" class="open:scale-1 complete:bg-(#008800) complete:scale-100" />
|
|
581
|
-
|
|
582
|
-
<View class="vertical">
|
|
583
|
-
<View id="letters" class="horizontal">
|
|
584
|
-
<Label class="wh-10 mx-1 rounded border-white bg-transparent text-center text-white" text="T" />
|
|
585
|
-
<Label class="wh-10 mx-1 rounded border-white bg-transparent text-center text-white" text="I" />
|
|
586
|
-
<Label class="wh-10 mx-1 rounded border-white bg-transparent text-center text-white" text="T" />
|
|
587
|
-
<Label class="wh-10 mx-1 rounded border-white bg-transparent text-center text-white" text="A" />
|
|
588
|
-
<Label class="wh-10 mx-1 rounded border-white bg-transparent text-center text-white" text="N" />
|
|
589
|
-
<Label class="wh-10 mx-1 rounded border-white bg-transparent text-center text-white" text="I" />
|
|
590
|
-
<Label class="wh-10 mx-1 rounded border-white bg-transparent text-center text-white" text="U" />
|
|
591
|
-
<Label class="wh-10 mx-1 rounded border-white bg-transparent text-center text-white" text="M" />
|
|
592
|
-
</View>
|
|
593
|
-
|
|
594
|
-
<Button title="Animate" class="mt-8" android:onClick="doAnimate" ios:onSingletap="doAnimate" />
|
|
595
|
-
<Button title="Reset" class="mt-4" android:onClick="doReset" ios:onSingletap="doReset" />
|
|
596
|
-
</View>
|
|
597
|
-
</Window>
|
|
598
|
-
</Alloy>
|
|
599
|
-
```
|
|
385
|
+
---
|
|
600
386
|
|
|
601
|
-
|
|
602
|
-
$.index.open()
|
|
387
|
+
## The `sequence` Method
|
|
603
388
|
|
|
604
|
-
|
|
605
|
-
$.myAnimationOpen.play($.letters.children)
|
|
606
|
-
}
|
|
389
|
+
Animates views one after another. Unlike `play(array)` which runs in parallel, `sequence` waits for each view to complete before starting the next.
|
|
607
390
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
}
|
|
391
|
+
```javascript
|
|
392
|
+
$.myAnimation.sequence(views, callback)
|
|
611
393
|
```
|
|
612
394
|
|
|
613
|
-
|
|
395
|
+
- The `open`/`close` state is toggled once for the entire sequence
|
|
396
|
+
- Each view fully completes before the next starts
|
|
397
|
+
- The callback fires once after the last view finishes
|
|
614
398
|
|
|
615
|
-
|
|
399
|
+
### Onboarding Reveal Example
|
|
616
400
|
|
|
617
401
|
```xml
|
|
618
|
-
<Animation class="
|
|
619
|
-
|
|
620
|
-
<
|
|
621
|
-
|
|
622
|
-
<View /> <!-- All children affected -->
|
|
623
|
-
</View>
|
|
402
|
+
<Animation id="revealAnim" module="purgetss.ui" class="open:opacity-100 close:opacity-0 duration-300" />
|
|
403
|
+
<Label id="title" class="opacity-0 text-2xl font-bold" text="Welcome" />
|
|
404
|
+
<Label id="subtitle" class="opacity-0 mt-2 text-lg text-gray-500" text="To the app" />
|
|
405
|
+
<Button id="cta" class="opacity-0 mt-4 rounded bg-blue-500 text-white" title="Get Started" />
|
|
624
406
|
```
|
|
625
407
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
```xml
|
|
631
|
-
<Animation class="child:0:bg-red-500 child:1:bg-blue-500" />
|
|
408
|
+
```javascript
|
|
409
|
+
$.fadeIn.sequence([$.title, $.subtitle, $.cta], () => {
|
|
410
|
+
console.log('All views animated in sequence')
|
|
411
|
+
})
|
|
632
412
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
<View /> <!-- Index 1: Blue background -->
|
|
636
|
-
</View>
|
|
413
|
+
// Use close() to force state back before revealing again
|
|
414
|
+
$.revealAnim.close(views)
|
|
637
415
|
```
|
|
638
416
|
|
|
639
417
|
---
|
|
640
418
|
|
|
641
|
-
##
|
|
419
|
+
## The `swap` Method
|
|
642
420
|
|
|
643
|
-
|
|
421
|
+
Exchanges positions of two views with animation.
|
|
644
422
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
```bash
|
|
648
|
-
purgetss icon-library -v=fa
|
|
649
|
-
```
|
|
650
|
-
:::
|
|
651
|
-
|
|
652
|
-
```xml title="index.xml"
|
|
653
|
-
<Alloy>
|
|
654
|
-
<Window class="exit-on-close-false portrait bg-purple-700">
|
|
655
|
-
<Animation id="draggableAnimation" module="purgetss.ui" class="bounds:m-4 bounds:mb-20" />
|
|
656
|
-
|
|
657
|
-
<!-- Sidebar -->
|
|
658
|
-
<Animation id="sideBarAnimation" module="purgetss.ui" class="close:w-24 duration-150 open:w-72" />
|
|
659
|
-
<Animation id="sideBarAnimationChevron" module="purgetss.ui" class="close:rotate-0 duration-150 open:rotate-180" />
|
|
660
|
-
|
|
661
|
-
<View id="sideBar" class="ml-2 h-1/2 w-24">
|
|
662
|
-
<View class="vertical ios:shadow-lg mr-8 rounded-lg bg-white" ios:onSingletap="doAction" android:onClick="doAction">
|
|
663
|
-
<View class="grid-flow-row">
|
|
664
|
-
<View class="grid-rows-7 ml-0 w-64">
|
|
665
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="home">
|
|
666
|
-
<Label class="touch-enabled-false fas fa-home ml-0 h-full w-16 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
667
|
-
<Label class="touch-enabled-false text-purple-700" text="Home" />
|
|
668
|
-
</View>
|
|
669
|
-
</View>
|
|
670
|
-
|
|
671
|
-
<View class="grid-rows-7 ml-0 w-64">
|
|
672
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="profile">
|
|
673
|
-
<Label class="touch-enabled-false fas fa-user ml-0 h-full w-16 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
674
|
-
<Label class="touch-enabled-false text-purple-700" text="Profile" />
|
|
675
|
-
</View>
|
|
676
|
-
</View>
|
|
677
|
-
|
|
678
|
-
<View class="grid-rows-7 ml-0 w-64">
|
|
679
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="messages">
|
|
680
|
-
<Label class="touch-enabled-false fas fa-comment ml-0 h-full w-16 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
681
|
-
<Label class="touch-enabled-false text-purple-700" text="Messages" />
|
|
682
|
-
</View>
|
|
683
|
-
</View>
|
|
684
|
-
|
|
685
|
-
<View class="grid-rows-7 ml-0 w-64">
|
|
686
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="help">
|
|
687
|
-
<Label class="touch-enabled-false fas fa-question-circle ml-0 h-full w-16 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
688
|
-
<Label class="touch-enabled-false text-purple-700" text="Help" />
|
|
689
|
-
</View>
|
|
690
|
-
</View>
|
|
691
|
-
|
|
692
|
-
<View class="grid-rows-7 ml-0 w-64">
|
|
693
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="settings">
|
|
694
|
-
<Label class="touch-enabled-false fas fa-cog ml-0 h-full w-16 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
695
|
-
<Label class="touch-enabled-false text-purple-700" text="Settings" />
|
|
696
|
-
</View>
|
|
697
|
-
</View>
|
|
698
|
-
|
|
699
|
-
<View class="grid-rows-7 ml-0 w-64">
|
|
700
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="password">
|
|
701
|
-
<Label class="touch-enabled-false fas fa-lock ml-0 h-full w-16 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
702
|
-
<Label class="touch-enabled-false text-purple-700" text="Password" />
|
|
703
|
-
</View>
|
|
704
|
-
</View>
|
|
705
|
-
|
|
706
|
-
<View class="grid-rows-7 ml-0 w-64">
|
|
707
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="sign-out">
|
|
708
|
-
<Label class="touch-enabled-false fas fa-sign-out-alt ml-0 h-full w-16 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
709
|
-
<Label class="touch-enabled-false text-purple-700" text="Sign Out" />
|
|
710
|
-
</View>
|
|
711
|
-
</View>
|
|
712
|
-
</View>
|
|
713
|
-
</View>
|
|
714
|
-
|
|
715
|
-
<Button id="sideBarChevron" class="fas rounded-10 fa-chevron-right mr-1.5 h-10 w-10 border-4 border-purple-700 bg-white text-xl text-purple-700" ios:onSingletap="sideBarClicked" android:onClick="sideBarClicked" />
|
|
716
|
-
|
|
717
|
-
</View>
|
|
718
|
-
|
|
719
|
-
<!-- My Card -->
|
|
720
|
-
<Animation id="myCardAnimation" module="purgetss.ui" class="open:h-(298) close:h-24 duration-150" />
|
|
721
|
-
<Animation id="myCardAnimationChevron" module="purgetss.ui" class="close:rotate-0 duration-150 open:rotate-180" />
|
|
722
|
-
|
|
723
|
-
<View id="myCard" class="mr-6 mt-6 h-24 w-8/12 rounded-lg shadow-lg">
|
|
724
|
-
<View class="vertical rounded-lg bg-white">
|
|
725
|
-
<View class="h-auto w-screen">
|
|
726
|
-
<ImageView class="rounded-16 m-4 ml-4 h-16 w-16" image="https://randomuser.me/api/portraits/women/17.jpg" />
|
|
727
|
-
|
|
728
|
-
<View class="vertical ml-24 h-auto">
|
|
729
|
-
<Label class="ml-0 text-sm font-bold text-gray-800" text="Someone Famous" />
|
|
730
|
-
<Label class="ml-0 text-xs font-bold text-gray-400" text="Website Designer" />
|
|
731
|
-
</View>
|
|
732
|
-
</View>
|
|
733
|
-
|
|
734
|
-
<View class="rounded-1 mx-2 h-0.5 w-screen bg-gray-300" />
|
|
735
|
-
|
|
736
|
-
<View class="bubble-parent-false mt-2 h-48 w-screen grid-flow-row" ios:onSingletap="doAction" android:onClick="doAction">
|
|
737
|
-
<View class="ml-0 w-screen grid-rows-5">
|
|
738
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="profile">
|
|
739
|
-
<Label class="touch-enabled-false fas fa-user ml-0 h-full w-14 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
740
|
-
<Label class="touch-enabled-false text-sm text-purple-700" text="Edit Profile" />
|
|
741
|
-
</View>
|
|
742
|
-
</View>
|
|
743
|
-
|
|
744
|
-
<View class="ml-0 w-screen grid-rows-5">
|
|
745
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="inbox">
|
|
746
|
-
<Label class="touch-enabled-false fas fa-inbox ml-0 h-full w-14 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
747
|
-
<Label class="touch-enabled-false text-sm text-purple-700" text="Inbox" />
|
|
748
|
-
</View>
|
|
749
|
-
</View>
|
|
750
|
-
|
|
751
|
-
<View class="ml-0 w-screen grid-rows-5">
|
|
752
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="settings">
|
|
753
|
-
<Label class="touch-enabled-false fas fa-cog ml-0 h-full w-14 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
754
|
-
<Label class="touch-enabled-false text-sm text-purple-700" text="Settings" />
|
|
755
|
-
</View>
|
|
756
|
-
</View>
|
|
757
|
-
|
|
758
|
-
<View class="ml-0 w-screen grid-rows-5">
|
|
759
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="support">
|
|
760
|
-
<Label class="touch-enabled-false fas fa-question-circle ml-0 h-full w-14 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
761
|
-
<Label class="touch-enabled-false text-sm text-purple-700" text="Support" />
|
|
762
|
-
</View>
|
|
763
|
-
</View>
|
|
764
|
-
|
|
765
|
-
<View class="ml-0 w-screen grid-rows-5">
|
|
766
|
-
<View class="horizontal bg-selected-purple-100 items-center" action="sign-out">
|
|
767
|
-
<Label class="touch-enabled-false fas fa-sign-out-alt ml-0 h-full w-14 border-transparent bg-transparent text-center text-xl text-purple-700" />
|
|
768
|
-
<Label class="touch-enabled-false text-sm text-purple-700" text="Sign Out" />
|
|
769
|
-
</View>
|
|
770
|
-
</View>
|
|
771
|
-
</View>
|
|
772
|
-
</View>
|
|
773
|
-
|
|
774
|
-
<View class="rounded-tl-br-md wh-8 bubble-parent-false mb-0 mr-0 bg-blue-400">
|
|
775
|
-
<Button id="myCardChevron" class="fas fa-chevron-down border-transparent bg-transparent text-white" ios:onSingletap="myCardClicked" android:onClick="myCardClicked" />
|
|
776
|
-
</View>
|
|
777
|
-
</View>
|
|
778
|
-
|
|
779
|
-
<Label id="action" class="mx-4 mb-6 h-10 w-screen rounded-lg bg-purple-800 text-sm font-bold text-purple-50" />
|
|
780
|
-
</Window>
|
|
781
|
-
</Alloy>
|
|
423
|
+
```javascript
|
|
424
|
+
$.myAnimation.swap(view1, view2)
|
|
782
425
|
```
|
|
783
426
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
427
|
+
**Behavior:**
|
|
428
|
+
- Inherits `duration`, `delay`, `curve` from Animation object. Fallback: **200ms**, **0ms**, **EASE_IN_OUT**
|
|
429
|
+
- Handles iOS transform reset automatically
|
|
430
|
+
- Temporarily elevates z-index; restores after completion
|
|
431
|
+
- Updates `_originLeft`/`_originTop` for subsequent drag operations
|
|
432
|
+
- **Automatic position normalization**: no explicit `top`/`left` needed -- resolved via `view.rect`
|
|
433
|
+
- **Bounce-back safe**: completes any in-progress bounce-back before swapping
|
|
788
434
|
|
|
789
|
-
|
|
790
|
-
$.sideBarAnimation.play($.sideBar)
|
|
791
|
-
$.sideBarAnimationChevron.play($.sideBarChevron)
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
function myCardClicked() {
|
|
795
|
-
$.myCardAnimation.play($.myCard)
|
|
796
|
-
$.myCardAnimationChevron.play($.myCardChevron)
|
|
797
|
-
}
|
|
435
|
+
### Memory Card Game Example
|
|
798
436
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
437
|
+
```javascript
|
|
438
|
+
let firstCard = null
|
|
439
|
+
function onCardTap({ source }) {
|
|
440
|
+
$.flipAnim.open(source)
|
|
441
|
+
if (!firstCard) { firstCard = source; return }
|
|
442
|
+
if (firstCard.valor === source.valor) {
|
|
443
|
+
firstCard = null
|
|
444
|
+
} else {
|
|
445
|
+
$.gameAnim.swap(firstCard, source)
|
|
446
|
+
setTimeout(() => { $.flipAnim.close([firstCard, source]); firstCard = null }, 500)
|
|
447
|
+
}
|
|
803
448
|
}
|
|
804
449
|
```
|
|
805
450
|
|
|
806
451
|
---
|
|
807
452
|
|
|
808
|
-
##
|
|
809
|
-
|
|
810
|
-
Along with the regular utilities like color, widths, and heights, you can set the following utilities on your animations:
|
|
811
|
-
|
|
812
|
-
### anchorPoint
|
|
813
|
-
|
|
814
|
-
Coordinate of the view about which to pivot an animation.
|
|
815
|
-
|
|
816
|
-
This is specified as a dictionary object with x and y properties, where `{x: 0.5, y: 0.5}` represents the center of whatever is being rotated.
|
|
817
|
-
|
|
818
|
-
**Default:** `(0.5, 0.5)`
|
|
819
|
-
|
|
820
|
-
```css
|
|
821
|
-
/* Property(ies): anchorPoint */
|
|
822
|
-
/* Component(s): Ti.UI.Animation, Ti.UI.View */
|
|
823
|
-
'.origin-center': { anchorPoint: { x: 0.5, y: 0.5 } }
|
|
824
|
-
'.origin-top': { anchorPoint: { x: 0.5, y: 0 } }
|
|
825
|
-
'.origin-top-right': { anchorPoint: { x: 1, y: 0 } }
|
|
826
|
-
'.origin-right': { anchorPoint: { x: 0.5, y: 1 } }
|
|
827
|
-
'.origin-bottom-right': { anchorPoint: { x: 1, y: 1 } }
|
|
828
|
-
'.origin-bottom': { anchorPoint: { x: 0.5, y: 1 } }
|
|
829
|
-
'.origin-bottom-left': { anchorPoint: { x: 0, y: 1 } }
|
|
830
|
-
'.origin-left': { anchorPoint: { x: 0, y: 0.5 } }
|
|
831
|
-
'.origin-top-left': { anchorPoint: { x: 0, y: 0 } }
|
|
832
|
-
|
|
833
|
-
/* anchor-point-{position} variant */
|
|
834
|
-
'.anchor-point-center': { anchorPoint: { x: 0.5, y: 0.5 } }
|
|
835
|
-
'.anchor-point-top': { anchorPoint: { x: 0.5, y: 0 } }
|
|
836
|
-
'.anchor-point-top-right': { anchorPoint: { x: 1, y: 0 } }
|
|
837
|
-
'.anchor-point-right': { anchorPoint: { x: 0.5, y: 1 } }
|
|
838
|
-
'.anchor-point-bottom-right': { anchorPoint: { x: 1, y: 1 } }
|
|
839
|
-
'.anchor-point-bottom': { anchorPoint: { x: 0.5, y: 1 } }
|
|
840
|
-
'.anchor-point-bottom-left': { anchorPoint: { x: 0, y: 1 } }
|
|
841
|
-
'.anchor-point-left': { anchorPoint: { x: 0, y: 0.5 } }
|
|
842
|
-
'.anchor-point-top-left': { anchorPoint: { x: 0, y: 0 } }
|
|
843
|
-
```
|
|
844
|
-
|
|
845
|
-
### autoreverse
|
|
453
|
+
## The `pulse` Method
|
|
846
454
|
|
|
847
|
-
|
|
455
|
+
Scales a view up and back using native `autoreverse` + `repeat`.
|
|
848
456
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
```css
|
|
852
|
-
/* Property: autoreverse */
|
|
853
|
-
/* Description: Specifies if the animation should be replayed in reverse upon completion. */
|
|
854
|
-
/* Component(s): Ti.UI.Animation */
|
|
855
|
-
'.autoreverse': { autoreverse: true }
|
|
856
|
-
'.autoreverse-false': { autoreverse: false }
|
|
857
|
-
```
|
|
858
|
-
|
|
859
|
-
### curve
|
|
860
|
-
|
|
861
|
-
Animation curve or easing function to apply to the animation.
|
|
862
|
-
|
|
863
|
-
This API can be assigned the following constants:
|
|
864
|
-
|
|
865
|
-
```css
|
|
866
|
-
/* Property: curve */
|
|
867
|
-
/* Description: Animation curve or easing function to apply to the animation. */
|
|
868
|
-
/* Component(s): Ti.UI.Animation */
|
|
869
|
-
'.curve-animation-ease-in': { curve: Ti.UI.ANIMATION_CURVE_EASE_IN }
|
|
870
|
-
'.curve-animation-ease-in-out': { curve: Ti.UI.ANIMATION_CURVE_EASE_IN_OUT }
|
|
871
|
-
'.curve-animation-ease-out': { curve: Ti.UI.ANIMATION_CURVE_EASE_OUT }
|
|
872
|
-
'.curve-animation-linear': { curve: Ti.UI.ANIMATION_CURVE_LINEAR }
|
|
457
|
+
```javascript
|
|
458
|
+
$.myAnimation.pulse(view, count)
|
|
873
459
|
```
|
|
874
460
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
```css
|
|
880
|
-
/* Property: delay */
|
|
881
|
-
/* Description: Delay, in milliseconds before starting the animation. */
|
|
882
|
-
/* Component(s): Ti.UI.Animation */
|
|
883
|
-
'.delay-0': { delay: 0 }
|
|
884
|
-
'.delay-25': { delay: 25 }
|
|
885
|
-
'.delay-50': { delay: 50 }
|
|
886
|
-
'.delay-75': { delay: 75 }
|
|
887
|
-
'.delay-100': { delay: 100 }
|
|
888
|
-
'.delay-150': { delay: 150 }
|
|
889
|
-
'.delay-200': { delay: 200 }
|
|
890
|
-
'.delay-250': { delay: 250 }
|
|
891
|
-
'.delay-300': { delay: 300 }
|
|
892
|
-
'.delay-350': { delay: 350 }
|
|
893
|
-
'.delay-400': { delay: 400 }
|
|
894
|
-
'.delay-450': { delay: 450 }
|
|
895
|
-
'.delay-500': { delay: 500 }
|
|
896
|
-
'.delay-600': { delay: 600 }
|
|
897
|
-
'.delay-700': { delay: 700 }
|
|
898
|
-
'.delay-800': { delay: 800 }
|
|
899
|
-
'.delay-900': { delay: 900 }
|
|
900
|
-
'.delay-1000': { delay: 1000 }
|
|
901
|
-
'.delay-2000': { delay: 2000 }
|
|
902
|
-
'.delay-3000': { delay: 3000 }
|
|
903
|
-
'.delay-4000': { delay: 4000 }
|
|
904
|
-
'.delay-5000': { delay: 5000 }
|
|
905
|
-
```
|
|
461
|
+
| Parameter | Type | Default | Description |
|
|
462
|
+
| --- | --- | --- | --- |
|
|
463
|
+
| `view` | `View` | -- | The view to pulse |
|
|
464
|
+
| `count` | `Number` | `1` | Number of pulses |
|
|
906
465
|
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
```css
|
|
912
|
-
/* Property: duration */
|
|
913
|
-
/* Component(s): Ti.UI.Animation */
|
|
914
|
-
'.duration-0': { duration: 0 }
|
|
915
|
-
'.duration-25': { duration: 25 }
|
|
916
|
-
'.duration-50': { duration: 50 }
|
|
917
|
-
'.duration-75': { duration: 75 }
|
|
918
|
-
'.duration-100': { duration: 100 }
|
|
919
|
-
'.duration-150': { duration: 150 }
|
|
920
|
-
'.duration-200': { duration: 200 }
|
|
921
|
-
'.duration-250': { duration: 250 }
|
|
922
|
-
'.duration-300': { duration: 300 }
|
|
923
|
-
'.duration-350': { duration: 350 }
|
|
924
|
-
'.duration-400': { duration: 400 }
|
|
925
|
-
'.duration-450': { duration: 450 }
|
|
926
|
-
'.duration-500': { duration: 500 }
|
|
927
|
-
'.duration-600': { duration: 600 }
|
|
928
|
-
'.duration-700': { duration: 700 }
|
|
929
|
-
'.duration-800': { duration: 800 }
|
|
930
|
-
'.duration-900': { duration: 900 }
|
|
931
|
-
'.duration-1000': { duration: 1000 }
|
|
932
|
-
'.duration-2000': { duration: 2000 }
|
|
933
|
-
'.duration-3000': { duration: 3000 }
|
|
934
|
-
'.duration-4000': { duration: 4000 }
|
|
935
|
-
'.duration-5000': { duration: 5000 }
|
|
936
|
-
```
|
|
466
|
+
- Scale from Animation object's `scale` class (e.g., `scale-(1.3)`). Fallback: **1.2x**
|
|
467
|
+
- Duration inherited; full cycle is double (up + back)
|
|
468
|
+
- Always uses `EASE_IN_OUT`; resets transform on completion
|
|
937
469
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
Number of times the animation should be performed.
|
|
941
|
-
|
|
942
|
-
If `autoreverse` is true, then one repeat of the animation consists of the animation being played once forward and once backward.
|
|
943
|
-
|
|
944
|
-
```css
|
|
945
|
-
/* Property: repeat */
|
|
946
|
-
/* Component(s): Ti.UI.Animation */
|
|
947
|
-
'.repeat-0': { repeat: 0 }
|
|
948
|
-
'.repeat-1': { repeat: 1 }
|
|
949
|
-
'.repeat-2': { repeat: 2 }
|
|
950
|
-
'.repeat-3': { repeat: 3 }
|
|
951
|
-
'.repeat-4': { repeat: 4 }
|
|
952
|
-
'.repeat-5': { repeat: 5 }
|
|
953
|
-
'.repeat-6': { repeat: 6 }
|
|
954
|
-
'.repeat-7': { repeat: 7 }
|
|
955
|
-
'.repeat-8': { repeat: 8 }
|
|
956
|
-
'.repeat-9': { repeat: 9 }
|
|
957
|
-
'.repeat-10': { repeat: 10 }
|
|
958
|
-
'.repeat-11': { repeat: 11 }
|
|
959
|
-
'.repeat-12': { repeat: 12 }
|
|
470
|
+
```xml
|
|
471
|
+
<Animation id="pulseAnim" module="purgetss.ui" class="scale-(1.3) autoreverse duration-150" />
|
|
960
472
|
```
|
|
961
473
|
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
This is specified as the rotation angle in degrees.
|
|
967
|
-
|
|
968
|
-
**Default:** `No rotation.`
|
|
969
|
-
|
|
970
|
-
```css
|
|
971
|
-
/* Property: rotate */
|
|
972
|
-
/* Component(s): MatrixCreationDict, Matrix2DCreationDict */
|
|
973
|
-
'.rotate-0': { rotate: 0 }
|
|
974
|
-
'.rotate-1': { rotate: 1 }
|
|
975
|
-
'.rotate-2': { rotate: 2 }
|
|
976
|
-
'.rotate-3': { rotate: 3 }
|
|
977
|
-
'.rotate-6': { rotate: 6 }
|
|
978
|
-
'.rotate-12': { rotate: 12 }
|
|
979
|
-
'.rotate-45': { rotate: 45 }
|
|
980
|
-
'.rotate-90': { rotate: 90 }
|
|
981
|
-
'.rotate-180': { rotate: 180 }
|
|
982
|
-
|
|
983
|
-
/* Property(ies): rotate ( Negative values ) */
|
|
984
|
-
/* Component(s): For the Animation Component */
|
|
985
|
-
'.-rotate-0': { rotate: 0 }
|
|
986
|
-
'.-rotate-1': { rotate: -1 }
|
|
987
|
-
'.-rotate-2': { rotate: -2 }
|
|
988
|
-
'.-rotate-3': { rotate: -3 }
|
|
989
|
-
'.-rotate-6': { rotate: -6 }
|
|
990
|
-
'.-rotate-12': { rotate: -12 }
|
|
991
|
-
'.-rotate-45': { rotate: -45 }
|
|
992
|
-
'.-rotate-90': { rotate: -90 }
|
|
993
|
-
'.-rotate-180': { rotate: -180 }
|
|
474
|
+
```javascript
|
|
475
|
+
$.pulseAnim.pulse($.badge)
|
|
476
|
+
$.pulseAnim.pulse($.badge, 3)
|
|
994
477
|
```
|
|
995
478
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
Scales the matrix by the specified scaling factor. The same scaling factor is used for both horizontal and vertical scaling.
|
|
999
|
-
|
|
1000
|
-
**Default:** `1`
|
|
1001
|
-
|
|
1002
|
-
```css
|
|
1003
|
-
/* Property: scale */
|
|
1004
|
-
/* Component(s): MatrixCreationDict, Matrix2DCreationDict, Matrix3DCreationDict */
|
|
1005
|
-
'.scale-0': { scale: 0 }
|
|
1006
|
-
'.scale-1': { scale: 0.01 }
|
|
1007
|
-
'.scale-5': { scale: 0.05 }
|
|
1008
|
-
'.scale-10': { scale: 0.10 }
|
|
1009
|
-
'.scale-25': { scale: 0.25 }
|
|
1010
|
-
'.scale-50': { scale: 0.5 }
|
|
1011
|
-
'.scale-75': { scale: 0.75 }
|
|
1012
|
-
'.scale-90': { scale: 0.9 }
|
|
1013
|
-
'.scale-95': { scale: 0.95 }
|
|
1014
|
-
'.scale-100': { scale: 1 }
|
|
1015
|
-
'.scale-105': { scale: 1.05 }
|
|
1016
|
-
'.scale-110': { scale: 1.1 }
|
|
1017
|
-
'.scale-125': { scale: 1.25 }
|
|
1018
|
-
'.scale-150': { scale: 1.5 }
|
|
1019
|
-
```
|
|
479
|
+
---
|
|
1020
480
|
|
|
1021
|
-
|
|
481
|
+
## The `shake` Method
|
|
1022
482
|
|
|
1023
|
-
|
|
483
|
+
Horizontal shake for error/feedback.
|
|
1024
484
|
|
|
1025
|
-
```
|
|
1026
|
-
|
|
1027
|
-
/* Component(s): For the Animation Component */
|
|
1028
|
-
'.drag-apply': { draggingType: 'apply' }
|
|
1029
|
-
'.drag-animate': { draggingType: 'animate' }
|
|
485
|
+
```javascript
|
|
486
|
+
$.myAnimation.shake(view, intensity)
|
|
1030
487
|
```
|
|
1031
488
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
489
|
+
| Parameter | Type | Default | Description |
|
|
490
|
+
| --- | --- | --- | --- |
|
|
491
|
+
| `view` | `View` | -- | The view to shake |
|
|
492
|
+
| `intensity` | `Number` | `10` | Horizontal displacement in pixels |
|
|
1035
493
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
'.opacity-to-100': { opacity: 0, animationProperties: { open: { opacity: 1 }, close: { opacity: 0 } } }
|
|
1041
|
-
'.toggle-visible': { animationProperties: { open: { visible: true }, close: { visible: false } } }
|
|
1042
|
-
```
|
|
494
|
+
- `duration`: inherited, divided by 6 for each shake cycle. Fallback: 400ms
|
|
495
|
+
- `delay`: inherited, applied before shake starts
|
|
496
|
+
- `curve`: always `EASE_IN_OUT` (fixed)
|
|
497
|
+
- `autoreverse` and `repeat`: always `true` and `3` (fixed)
|
|
1043
498
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
It will initially set the view's scale to the specified value and then animate it to 1.
|
|
1049
|
-
|
|
1050
|
-
```css
|
|
1051
|
-
/* Property(ies): animationProperties - scales the view (in or out) and resets it to 100% when the animation completes */
|
|
1052
|
-
/* Component(s): Animation */
|
|
1053
|
-
'.zoom-in-0': { animationProperties: { open: { scale: 0 }, complete: { scale: 1 } } }
|
|
1054
|
-
'.zoom-in-1': { animationProperties: { open: { scale: 0.01 }, complete: { scale: 1 } } }
|
|
1055
|
-
'.zoom-in-5': { animationProperties: { open: { scale: 0.05 }, complete: { scale: 1 } } }
|
|
1056
|
-
'.zoom-in-10': { animationProperties: { open: { scale: 0.10 }, complete: { scale: 1 } } }
|
|
1057
|
-
'.zoom-in-25': { animationProperties: { open: { scale: 0.25 }, complete: { scale: 1 } } }
|
|
1058
|
-
'.zoom-in-50': { animationProperties: { open: { scale: 0.5 }, complete: { scale: 1 } } }
|
|
1059
|
-
'.zoom-in-75': { animationProperties: { open: { scale: 0.75 }, complete: { scale: 1 } } }
|
|
1060
|
-
'.zoom-in-90': { animationProperties: { open: { scale: 0.9 }, complete: { scale: 1 } } }
|
|
1061
|
-
'.zoom-in-95': { animationProperties: { open: { scale: 0.95 }, complete: { scale: 1 } } }
|
|
1062
|
-
'.zoom-in-100': { animationProperties: { open: { scale: 1 }, complete: { scale: 1 } } }
|
|
1063
|
-
'.zoom-in-105': { animationProperties: { open: { scale: 1.05 }, complete: { scale: 1 } } }
|
|
1064
|
-
'.zoom-in-110': { animationProperties: { open: { scale: 1.1 }, complete: { scale: 1 } } }
|
|
1065
|
-
'.zoom-in-125': { animationProperties: { open: { scale: 1.25 }, complete: { scale: 1 } } }
|
|
1066
|
-
'.zoom-in-150': { animationProperties: { open: { scale: 1.5 }, complete: { scale: 1 } } }
|
|
1067
|
-
'.zoom-out-0': { animationProperties: { close: { scale: 0 }, complete: { scale: 1 } } }
|
|
1068
|
-
'.zoom-out-1': { animationProperties: { close: { scale: 0.01 }, complete: { scale: 1 } } }
|
|
1069
|
-
'.zoom-out-5': { animationProperties: { close: { scale: 0.05 }, complete: { scale: 1 } } }
|
|
1070
|
-
'.zoom-out-10': { animationProperties: { close: { scale: 0.10 }, complete: { scale: 1 } } }
|
|
1071
|
-
'.zoom-out-25': { animationProperties: { close: { scale: 0.25 }, complete: { scale: 1 } } }
|
|
1072
|
-
'.zoom-out-50': { animationProperties: { close: { scale: 0.5 }, complete: { scale: 1 } } }
|
|
1073
|
-
'.zoom-out-75': { animationProperties: { close: { scale: 0.75 }, complete: { scale: 1 } } }
|
|
1074
|
-
'.zoom-out-90': { animationProperties: { close: { scale: 0.9 }, complete: { scale: 1 } } }
|
|
1075
|
-
'.zoom-out-95': { animationProperties: { close: { scale: 0.95 }, complete: { scale: 1 } } }
|
|
1076
|
-
'.zoom-out-100': { animationProperties: { close: { scale: 1 }, complete: { scale: 1 } } }
|
|
1077
|
-
'.zoom-out-105': { animationProperties: { close: { scale: 1.05 }, complete: { scale: 1 } } }
|
|
1078
|
-
'.zoom-out-110': { animationProperties: { close: { scale: 1.1 }, complete: { scale: 1 } } }
|
|
1079
|
-
'.zoom-out-125': { animationProperties: { close: { scale: 1.25 }, complete: { scale: 1 } } }
|
|
1080
|
-
'.zoom-out-150': { animationProperties: { close: { scale: 1.5 }, complete: { scale: 1 } } }
|
|
499
|
+
```javascript
|
|
500
|
+
$.errorAnim.shake($.emailField, 5)
|
|
501
|
+
$.emailField.applyProperties({ borderColor: '#ef4444' })
|
|
1081
502
|
```
|
|
1082
503
|
|
|
1083
504
|
---
|
|
1084
505
|
|
|
1085
|
-
##
|
|
1086
|
-
|
|
1087
|
-
### 1. Use Semantic IDs
|
|
506
|
+
## The `snapTo` Method
|
|
1088
507
|
|
|
1089
|
-
|
|
1090
|
-
<!-- Good -->
|
|
1091
|
-
<Animation id="fadeIn" class="close:opacity-0 open:opacity-100" />
|
|
1092
|
-
<Animation id="expandCard" class="close:h-20 open:h-40" />
|
|
508
|
+
Snaps a view to the nearest target by center-to-center Euclidean distance. Returns the matched target or `null`.
|
|
1093
509
|
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
<Animation id="anim2" class="..." />
|
|
510
|
+
```javascript
|
|
511
|
+
const matched = $.myAnimation.snapTo(view, targets)
|
|
1097
512
|
```
|
|
1098
513
|
|
|
1099
|
-
|
|
514
|
+
- Inherits `duration`, `delay`, `curve`. Fallback: **200ms**, **0ms**, **EASE_IN_OUT**
|
|
515
|
+
- Handles iOS transform reset; updates `_originLeft`/`_originTop`
|
|
516
|
+
- Automatic position normalization
|
|
517
|
+
|
|
518
|
+
### Puzzle Game with Collision Detection
|
|
1100
519
|
|
|
1101
520
|
```javascript
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
521
|
+
$.puzzleAnim.draggable(pieces)
|
|
522
|
+
$.puzzleAnim.detectCollisions(pieces.concat(slots),
|
|
523
|
+
null,
|
|
524
|
+
(source, target) => {
|
|
525
|
+
if (source.valor === target.valor) {
|
|
526
|
+
$.puzzleAnim.undraggable(source)
|
|
527
|
+
source.applyProperties({ opacity: 0.6 })
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
)
|
|
1107
531
|
```
|
|
1108
532
|
|
|
1109
|
-
|
|
533
|
+
`snap-center` auto-centers on the slot; `snap-back` returns to origin if dropped outside; `undraggable` locks when correct.
|
|
1110
534
|
|
|
1111
|
-
|
|
1112
|
-
<Animation class="complete:scale-100 duration-200 open:scale-110" />
|
|
1113
|
-
```
|
|
535
|
+
---
|
|
1114
536
|
|
|
1115
|
-
|
|
537
|
+
## The `reorder` Method
|
|
1116
538
|
|
|
1117
|
-
|
|
1118
|
-
<Animation class="children:opacity-0 complete:opacity-100 duration-300" />
|
|
539
|
+
Animates views to new positions by index mapping. All views animate simultaneously.
|
|
1119
540
|
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
<View /> <!-- All fade in together -->
|
|
1123
|
-
</View>
|
|
541
|
+
```javascript
|
|
542
|
+
$.myAnimation.reorder(views, newOrder)
|
|
1124
543
|
```
|
|
1125
544
|
|
|
1126
|
-
|
|
545
|
+
- `newOrder` maps current index to new position: `[2, 1, 0]` reverses, `[1, 2, 0]` rotates
|
|
546
|
+
- Length must match `views` length
|
|
547
|
+
- Inherits `duration`, `delay`, `curve`. Fallback: **200ms**, **0ms**, **EASE_IN_OUT**
|
|
548
|
+
- Automatic position normalization
|
|
1127
549
|
|
|
1128
550
|
```javascript
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
551
|
+
const tasks = [$.taskHigh, $.taskMedium, $.taskLow]
|
|
552
|
+
$.taskAnim.reorder(tasks, [2, 1, 0]) // reverse order
|
|
553
|
+
$.taskAnim.reorder(tasks, [1, 2, 0]) // rotate
|
|
1132
554
|
```
|
|
1133
555
|
|
|
1134
556
|
---
|
|
1135
557
|
|
|
1136
|
-
##
|
|
1137
|
-
|
|
1138
|
-
### Modal Fade In/Out
|
|
558
|
+
## The `transition` Method
|
|
1139
559
|
|
|
1140
|
-
|
|
1141
|
-
<Animation id="modalFade" class="close:opacity-0 open:opacity-100" />
|
|
1142
|
-
|
|
1143
|
-
<View id="modalView" class="opacity-0">
|
|
1144
|
-
<!-- Modal content -->
|
|
1145
|
-
</View>
|
|
1146
|
-
```
|
|
560
|
+
Animates multiple views simultaneously to layout positions defined by `Matrix2D.translate().rotate().scale()`.
|
|
1147
561
|
|
|
1148
562
|
```javascript
|
|
1149
|
-
|
|
1150
|
-
$.modalFade.open($.modalView)
|
|
1151
|
-
|
|
1152
|
-
// Close
|
|
1153
|
-
$.modalFade.close($.modalView)
|
|
563
|
+
$.myAnimation.transition(views, layouts)
|
|
1154
564
|
```
|
|
1155
565
|
|
|
1156
|
-
###
|
|
566
|
+
### Layout Object Properties
|
|
1157
567
|
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
568
|
+
| Property | Type | Default | Description |
|
|
569
|
+
| --- | --- | --- | --- |
|
|
570
|
+
| `translation` | `Object` | `{x:0, y:0}` | Translation offset in pixels |
|
|
571
|
+
| `rotate` | `Number` | `0` | Rotation in degrees |
|
|
572
|
+
| `scale` | `Number` | `1` | Scale factor |
|
|
573
|
+
| `zIndex` | `Number` | -- | Applied synchronously before animation |
|
|
574
|
+
| `width` | `Number` | -- | Optional width change |
|
|
575
|
+
| `height` | `Number` | -- | Optional height change |
|
|
576
|
+
| `opacity` | `Number` | -- | Optional opacity change |
|
|
1161
577
|
|
|
1162
|
-
###
|
|
578
|
+
### Behavior
|
|
1163
579
|
|
|
1164
|
-
|
|
1165
|
-
|
|
580
|
+
- Inherits `duration`, `delay`, `curve` from Animation object
|
|
581
|
+
- Each view gets a single `Ti.UI.createAnimation()` with combined `Matrix2D` transform
|
|
582
|
+
- All animations launch simultaneously
|
|
583
|
+
- `zIndex` applied synchronously before animation starts
|
|
584
|
+
- **Mismatched lengths**: extra views fade out; extra layouts ignored; faded views fade back in when given a layout entry
|
|
1166
585
|
|
|
1167
|
-
|
|
1168
|
-
<!-- Card content -->
|
|
1169
|
-
</View>
|
|
1170
|
-
```
|
|
586
|
+
### Reusable Presets
|
|
1171
587
|
|
|
1172
588
|
```javascript
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
}
|
|
589
|
+
const fanOut = [
|
|
590
|
+
{ translation: { x: -120, y: 20 }, rotate: -15, scale: 0.8, zIndex: 1 },
|
|
591
|
+
{ translation: { x: 0, y: 0 }, rotate: 0, scale: 1, zIndex: 3 },
|
|
592
|
+
{ translation: { x: 120, y: 20 }, rotate: 15, scale: 0.8, zIndex: 2 }
|
|
593
|
+
]
|
|
594
|
+
|
|
595
|
+
const stack = [
|
|
596
|
+
{ translation: { x: -8, y: 16 }, rotate: 0, scale: 0.9, zIndex: 1 },
|
|
597
|
+
{ translation: { x: 0, y: 8 }, rotate: 0, scale: 0.95, zIndex: 2 },
|
|
598
|
+
{ translation: { x: 8, y: 0 }, rotate: 0, scale: 1, zIndex: 3 }
|
|
599
|
+
]
|
|
600
|
+
|
|
601
|
+
// Same preset, different view groups
|
|
602
|
+
$.anim.transition(screensA, fanOut)
|
|
603
|
+
$.anim.transition(screensB, fanOut)
|
|
1176
604
|
```
|
|
1177
605
|
|
|
1178
|
-
###
|
|
606
|
+
### Photo Gallery Example
|
|
1179
607
|
|
|
1180
608
|
```xml
|
|
1181
|
-
<Animation id="
|
|
1182
|
-
|
|
1183
|
-
<View id="card" class="h-32 w-64 bg-white shadow" />
|
|
609
|
+
<Animation id="galleryAnim" module="purgetss.ui" class="keep-z-index duration-150" />
|
|
1184
610
|
```
|
|
1185
611
|
|
|
1186
612
|
```javascript
|
|
1187
|
-
$.
|
|
613
|
+
const photos = [$.photo1, $.photo2, $.photo3]
|
|
614
|
+
function doFan() { $.galleryAnim.transition(photos, fan) }
|
|
615
|
+
function doStack() { $.galleryAnim.transition(photos, stack) }
|
|
616
|
+
$.galleryAnim.draggable(photos) // photos keep rotation/scale while dragging
|
|
1188
617
|
```
|
|
1189
618
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
## Animation Properties Summary
|
|
619
|
+
`keep-z-index` preserves the layout order during drag.
|
|
1193
620
|
|
|
1194
|
-
###
|
|
621
|
+
### Mac Catalyst Note
|
|
1195
622
|
|
|
1196
|
-
|
|
1197
|
-
| ----------- | ------------------------ | ------------------------------ |
|
|
1198
|
-
| `open:` | Opening state properties | `open:opacity-100 open:w-full` |
|
|
1199
|
-
| `close:` | Closing state properties | `close:opacity-0 close:h-0` |
|
|
1200
|
-
| `complete:` | Post-open state | `complete:bg-green-500` |
|
|
1201
|
-
| `children:` | All children affected | `children:opacity-50` |
|
|
1202
|
-
| `child:{n}` | Specific child by index | `child:0:bg-red-500` |
|
|
1203
|
-
| `drag:` | Dragging state | `drag:opacity-50` |
|
|
1204
|
-
| `drop:` | Dropped state | `drop:scale-95` |
|
|
1205
|
-
| `bounds:` | Movement limits | `bounds:m-4` |
|
|
623
|
+
On Mac Catalyst, parent containers of transitioned views should use **fixed dimensions** (not `Ti.UI.FILL`). Resizable containers trigger a UIKit re-layout that distorts rotated `Matrix2D` transforms. This does not affect iOS or Android.
|
|
1206
624
|
|
|
1207
|
-
|
|
625
|
+
---
|
|
1208
626
|
|
|
1209
|
-
|
|
1210
|
-
| --------------------------------------------------- | ----------------------------- | ---------------------------------- |
|
|
1211
|
-
| `delay-{ms}` | Delay before animation starts | `delay-300` |
|
|
1212
|
-
| `duration-{ms}` | Duration of animation | `duration-500` |
|
|
1213
|
-
| `ease-in`, `ease-out`, `ease-linear`, `ease-in-out` | Animation curve | `ease-out` |
|
|
1214
|
-
| `rotate-{degrees}` | Rotation | `rotate-45`, `-rotate-90` |
|
|
1215
|
-
| `scale-{0-150}` | Scale | `scale-110` |
|
|
1216
|
-
| `repeat-{n}` | Repetitions | `repeat-3` |
|
|
1217
|
-
| `autoreverse` | Auto-reverse on completion | `autoreverse` |
|
|
1218
|
-
| `zoom-in-{0-150}` | Zoom in effect | `zoom-in-125` |
|
|
1219
|
-
| `zoom-out-{0-150}` | Zoom out effect | `zoom-out-75` |
|
|
1220
|
-
| `drag-apply` | Instant drag properties | `drag-apply` |
|
|
1221
|
-
| `drag-animate` | Animated drag properties | `drag-animate` |
|
|
1222
|
-
| `horizontal-constraint` | Horizontal movement only | `horizontal-constraint` |
|
|
1223
|
-
| `vertical-constraint` | Vertical movement only | `vertical-constraint` |
|
|
1224
|
-
| `opacity-to-0` | Fade out | `opacity-to-0` |
|
|
1225
|
-
| `opacity-to-100` | Fade in | `opacity-to-100` |
|
|
1226
|
-
| `toggle-visible` | Visibility toggle | `toggle-visible` |
|
|
1227
|
-
| `origin-*` | Anchor point | `origin-center`, `origin-top-left` |
|
|
627
|
+
For property inheritance, timing/utility classes, utility functions, implementation rules, and complex UI examples, see [animation-advanced.md](./animation-advanced.md).
|