UNPKG

12.5 kBJavaScriptView Raw
1import { Animation } from '../animation';
2import { View } from '../core/view';
3import { isObject, isFunction } from '../../utils/types';
4import { GestureEvents, GestureStateTypes, GestureTypes } from './gestures-common';
5export var TouchAnimationTypes;
6(function (TouchAnimationTypes) {
7 TouchAnimationTypes["up"] = "up";
8 TouchAnimationTypes["down"] = "down";
9})(TouchAnimationTypes || (TouchAnimationTypes = {}));
10/**
11 * Manage interactivity in your apps easily with TouchManager.
12 * Store reusable down/up animation settings for touches as well as optionally enable automatic tap (down/up) animations for your app.
13 */
14export class TouchManager {
15 /**
16 * The TouchManager uses this internally.
17 * Adds touch animations to view based upon it's touchAnimation property or TouchManager.animations.
18 * @param view NativeScript view instance
19 */
20 static addAnimations(view) {
21 const handleDown = (view?.touchAnimation && (view?.touchAnimation).down) || (TouchManager.animations && TouchManager.animations.down);
22 const handleUp = (view?.touchAnimation && (view?.touchAnimation).up) || (TouchManager.animations && TouchManager.animations.up);
23 if (__APPLE__) {
24 if (view?.ios?.addTargetActionForControlEvents) {
25 // can use UIControlEvents
26 if (!TouchManager.touchHandlers) {
27 TouchManager.touchHandlers = [];
28 }
29 TouchManager.touchHandlers.push({
30 view,
31 handler: TouchControlHandler.initWithOwner(new WeakRef(view)),
32 });
33 if (handleDown) {
34 view.ios.addTargetActionForControlEvents(TouchManager.touchHandlers[TouchManager.touchHandlers.length - 1].handler, GestureEvents.touchDown, 1 /* UIControlEvents.TouchDown */ | 16 /* UIControlEvents.TouchDragEnter */);
35 view.on(GestureEvents.touchDown, (args) => {
36 TouchManager.startAnimationForType(view, TouchAnimationTypes.down);
37 });
38 }
39 if (handleUp) {
40 view.ios.addTargetActionForControlEvents(TouchManager.touchHandlers[TouchManager.touchHandlers.length - 1].handler, GestureEvents.touchUp, 32 /* UIControlEvents.TouchDragExit */ | 256 /* UIControlEvents.TouchCancel */ | 64 /* UIControlEvents.TouchUpInside */ | 128 /* UIControlEvents.TouchUpOutside */);
41 view.on(GestureEvents.touchUp, (args) => {
42 TouchManager.startAnimationForType(view, TouchAnimationTypes.up);
43 });
44 }
45 }
46 else {
47 if (handleDown || handleUp) {
48 view.on(GestureEvents.gestureAttached, (args) => {
49 if (args.type === GestureTypes.longPress) {
50 args.ios.minimumPressDuration = args.object?.touchDelay || 0;
51 }
52 });
53 view.on(GestureTypes.longPress, (args) => {
54 switch (args.state) {
55 case GestureStateTypes.began:
56 if (handleDown) {
57 TouchManager.startAnimationForType(args.view, TouchAnimationTypes.down);
58 }
59 break;
60 case GestureStateTypes.cancelled:
61 case GestureStateTypes.ended:
62 if (handleUp) {
63 TouchManager.startAnimationForType(args.view, TouchAnimationTypes.up);
64 }
65 break;
66 }
67 });
68 }
69 }
70 }
71 else {
72 if (handleDown || handleUp) {
73 view.on(GestureTypes.touch, (args) => {
74 switch (args.action) {
75 case 'down':
76 if (handleDown) {
77 view.notify({
78 eventName: GestureEvents.touchDown,
79 object: view,
80 data: args.android,
81 });
82 }
83 break;
84 case 'up':
85 case 'cancel':
86 if (handleUp) {
87 view.notify({
88 eventName: GestureEvents.touchUp,
89 object: view,
90 data: args.android,
91 });
92 }
93 break;
94 }
95 });
96 if (handleDown) {
97 view.on(GestureEvents.touchDown, (args) => {
98 TouchManager.startAnimationForType(view, TouchAnimationTypes.down);
99 });
100 }
101 if (handleUp) {
102 view.on(GestureEvents.touchUp, (args) => {
103 TouchManager.startAnimationForType(view, TouchAnimationTypes.up);
104 });
105 }
106 }
107 }
108 view.on(View.disposeNativeViewEvent, (args) => {
109 const index = TouchManager.touchHandlers?.findIndex((handler) => handler.view === args.object);
110 if (index > -1) {
111 TouchManager.touchHandlers.splice(index, 1);
112 }
113 TouchManager.touchAnimationDefinitions = TouchManager.touchAnimationDefinitions?.filter((d) => d.view !== args.object);
114 });
115 }
116 static startAnimationForType(view, type) {
117 if (view) {
118 const animate = function (definition) {
119 if (definition) {
120 if (isFunction(definition)) {
121 definition(view);
122 }
123 else {
124 if (!TouchManager.touchAnimationDefinitions) {
125 TouchManager.touchAnimationDefinitions = [];
126 }
127 // reuse animations for each type
128 let touchAnimation;
129 // triggering animations should always cancel other animations which may be in progress
130 for (const d of TouchManager.touchAnimationDefinitions) {
131 if (d.view === view && d.animation) {
132 d.animation.cancel();
133 if (d.type === type) {
134 touchAnimation = d.animation;
135 }
136 }
137 }
138 if (!touchAnimation) {
139 touchAnimation = new Animation([
140 {
141 target: view,
142 ...definition,
143 },
144 ]);
145 TouchManager.touchAnimationDefinitions.push({
146 view,
147 type,
148 animation: touchAnimation,
149 });
150 }
151 touchAnimation.play().catch(() => { });
152 }
153 }
154 };
155 // always use instance defined animation over global
156 if (isObject(view.touchAnimation) && view.touchAnimation[type]) {
157 animate(view.touchAnimation[type]);
158 }
159 else if (TouchManager.animations?.[type]) {
160 // fallback to globally defined
161 animate(TouchManager.animations?.[type]);
162 }
163 }
164 }
165 /**
166 * The TouchManager uses this internally.
167 * Adds visionOS hover styles to views based upon it's visionHoverStyle property
168 * @param view NativeScript view instance
169 */
170 static addHoverStyle(view) {
171 if (__VISIONOS__ && view?.ios) {
172 if (!TouchManager.visionHoverOptions) {
173 TouchManager.visionHoverOptions = {};
174 }
175 if (!TouchManager.visionHoverOptions['default']) {
176 // Add default hoverStyle to apply everywhere (no custom hover style being defined on this view)
177 TouchManager.visionHoverOptions['default'] = {
178 effect: 'automatic',
179 };
180 }
181 if (!TouchManager.visionHoverStyleCache) {
182 TouchManager.visionHoverStyleCache = {};
183 }
184 const createHoverStyleFromOptions = function (options) {
185 let effect;
186 switch (options.effect) {
187 case 'automatic':
188 effect = UIHoverAutomaticEffect.effect();
189 break;
190 case 'highlight':
191 effect = UIHoverHighlightEffect.effect();
192 break;
193 case 'lift':
194 effect = UIHoverLiftEffect.effect();
195 break;
196 }
197 let shape;
198 switch (options.shape) {
199 case 'circle':
200 shape = UIShape.circleShape;
201 break;
202 case 'rect':
203 if (options.shapeCornerRadius) {
204 shape = UIShape.rectShapeWithCornerRadius(options.shapeCornerRadius);
205 }
206 else {
207 shape = UIShape.rectShape;
208 }
209 break;
210 }
211 return UIHoverStyle.styleWithEffectShape(effect, shape);
212 };
213 if (!TouchManager.visionHoverStyleCache['default']) {
214 const defaultOptions = TouchManager.visionHoverOptions['default'];
215 TouchManager.visionHoverStyleCache['default'] = createHoverStyleFromOptions(defaultOptions || {
216 effect: 'automatic',
217 });
218 }
219 if (view.visionHoverStyle) {
220 if (typeof view.visionHoverStyle === 'string') {
221 view.ios.hoverStyle = TouchManager.visionHoverStyleCache[view.visionHoverStyle] || TouchManager.visionHoverStyleCache['default'];
222 }
223 }
224 else {
225 view.ios.hoverStyle = TouchManager.visionHoverStyleCache['default'];
226 }
227 }
228 }
229}
230export let TouchControlHandler;
231ensureTouchControlHandlers();
232function ensureTouchControlHandlers() {
233 if (__APPLE__) {
234 var TouchHandlerImpl = /** @class */ (function (_super) {
235 __extends(TouchHandlerImpl, _super);
236 function TouchHandlerImpl() {
237 return _super !== null && _super.apply(this, arguments) || this;
238 }
239 TouchHandlerImpl.initWithOwner = function (owner) {
240 var handler = TouchHandlerImpl.new();
241 handler._owner = owner;
242 return handler;
243 };
244 TouchHandlerImpl.prototype.touchDown = function (args) {
245 var _a, _b, _c, _d;
246 (_b = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref) === null || _b === void 0 ? void 0 : _b.call(_a).notify({
247 eventName: GestureEvents.touchDown,
248 object: (_d = (_c = this._owner) === null || _c === void 0 ? void 0 : _c.deref) === null || _d === void 0 ? void 0 : _d.call(_c),
249 data: args,
250 });
251 };
252 TouchHandlerImpl.prototype.touchUp = function (args) {
253 var _a, _b, _c, _d;
254 (_b = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref) === null || _b === void 0 ? void 0 : _b.call(_a).notify({
255 eventName: GestureEvents.touchUp,
256 object: (_d = (_c = this._owner) === null || _c === void 0 ? void 0 : _c.deref) === null || _d === void 0 ? void 0 : _d.call(_c),
257 data: args,
258 });
259 };
260 TouchHandlerImpl.ObjCExposedMethods = {
261 touchDown: { returns: interop.types.void, params: [interop.types.id] },
262 touchUp: { returns: interop.types.void, params: [interop.types.id] },
263 };
264 return TouchHandlerImpl;
265}(NSObject));
266 TouchControlHandler = TouchHandlerImpl;
267 }
268}
269//# sourceMappingURL=touch-manager.js.map
\No newline at end of file