UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

268 lines • 12.5 kB
import { Animation } from '../animation'; import { isObject, isFunction } from '../../utils/types'; import { GestureEvents, GestureStateTypes, GestureTypes } from './gestures-common'; export var TouchAnimationTypes; (function (TouchAnimationTypes) { TouchAnimationTypes["up"] = "up"; TouchAnimationTypes["down"] = "down"; })(TouchAnimationTypes || (TouchAnimationTypes = {})); /** * Manage interactivity in your apps easily with TouchManager. * Store reusable down/up animation settings for touches as well as optionally enable automatic tap (down/up) animations for your app. */ export class TouchManager { /** * The TouchManager uses this internally. * Adds touch animations to view based upon it's touchAnimation property or TouchManager.animations. * @param view NativeScript view instance */ static addAnimations(view) { const handleDown = (view?.touchAnimation && (view?.touchAnimation).down) || (TouchManager.animations && TouchManager.animations.down); const handleUp = (view?.touchAnimation && (view?.touchAnimation).up) || (TouchManager.animations && TouchManager.animations.up); if (__APPLE__) { if (view?.ios?.addTargetActionForControlEvents) { // can use UIControlEvents if (!TouchManager.touchHandlers) { TouchManager.touchHandlers = []; } TouchManager.touchHandlers.push({ view, handler: TouchControlHandler.initWithOwner(new WeakRef(view)), }); if (handleDown) { view.ios.addTargetActionForControlEvents(TouchManager.touchHandlers[TouchManager.touchHandlers.length - 1].handler, GestureEvents.touchDown, 1 /* UIControlEvents.TouchDown */ | 16 /* UIControlEvents.TouchDragEnter */); view.on(GestureEvents.touchDown, (args) => { TouchManager.startAnimationForType(view, TouchAnimationTypes.down); }); } if (handleUp) { view.ios.addTargetActionForControlEvents(TouchManager.touchHandlers[TouchManager.touchHandlers.length - 1].handler, GestureEvents.touchUp, 32 /* UIControlEvents.TouchDragExit */ | 256 /* UIControlEvents.TouchCancel */ | 64 /* UIControlEvents.TouchUpInside */ | 128 /* UIControlEvents.TouchUpOutside */); view.on(GestureEvents.touchUp, (args) => { TouchManager.startAnimationForType(view, TouchAnimationTypes.up); }); } } else { if (handleDown || handleUp) { view.on(GestureEvents.gestureAttached, (args) => { if (args.type === GestureTypes.longPress) { args.ios.minimumPressDuration = args.object?.touchDelay || 0; } }); view.on(GestureTypes[GestureTypes.longPress], (args) => { switch (args.state) { case GestureStateTypes.began: if (handleDown) { TouchManager.startAnimationForType(args.view, TouchAnimationTypes.down); } break; case GestureStateTypes.cancelled: case GestureStateTypes.ended: if (handleUp) { TouchManager.startAnimationForType(args.view, TouchAnimationTypes.up); } break; } }); } } } else { if (handleDown || handleUp) { view.on(GestureTypes[GestureTypes.touch], (args) => { switch (args.action) { case 'down': if (handleDown) { view.notify({ eventName: GestureEvents.touchDown, object: view, data: args.android, }); } break; case 'up': case 'cancel': if (handleUp) { view.notify({ eventName: GestureEvents.touchUp, object: view, data: args.android, }); } break; } }); if (handleDown) { view.on(GestureEvents.touchDown, (args) => { TouchManager.startAnimationForType(view, TouchAnimationTypes.down); }); } if (handleUp) { view.on(GestureEvents.touchUp, (args) => { TouchManager.startAnimationForType(view, TouchAnimationTypes.up); }); } } } view.on('disposeNativeView', (args) => { const index = TouchManager.touchHandlers?.findIndex((handler) => handler.view === args.object); if (index > -1) { TouchManager.touchHandlers.splice(index, 1); } TouchManager.touchAnimationDefinitions = TouchManager.touchAnimationDefinitions?.filter((d) => d.view !== args.object); }); } static startAnimationForType(view, type) { if (view) { const animate = function (definition) { if (definition) { if (isFunction(definition)) { definition(view); } else { if (!TouchManager.touchAnimationDefinitions) { TouchManager.touchAnimationDefinitions = []; } // reuse animations for each type let touchAnimation; // triggering animations should always cancel other animations which may be in progress for (const d of TouchManager.touchAnimationDefinitions) { if (d.view === view && d.animation) { d.animation.cancel(); if (d.type === type) { touchAnimation = d.animation; } } } if (!touchAnimation) { touchAnimation = new Animation([ { target: view, ...definition, }, ]); TouchManager.touchAnimationDefinitions.push({ view, type, animation: touchAnimation, }); } touchAnimation.play().catch(() => { }); } } }; // always use instance defined animation over global if (isObject(view.touchAnimation) && view.touchAnimation[type]) { animate(view.touchAnimation[type]); } else if (TouchManager.animations?.[type]) { // fallback to globally defined animate(TouchManager.animations?.[type]); } } } /** * The TouchManager uses this internally. * Adds visionOS hover styles to views based upon it's visionHoverStyle property * @param view NativeScript view instance */ static addHoverStyle(view) { if (__VISIONOS__ && view?.ios) { if (!TouchManager.visionHoverOptions) { TouchManager.visionHoverOptions = {}; } if (!TouchManager.visionHoverOptions['default']) { // Add default hoverStyle to apply everywhere (no custom hover style being defined on this view) TouchManager.visionHoverOptions['default'] = { effect: 'automatic', }; } if (!TouchManager.visionHoverStyleCache) { TouchManager.visionHoverStyleCache = {}; } const createHoverStyleFromOptions = function (options) { let effect; switch (options.effect) { case 'automatic': effect = UIHoverAutomaticEffect.effect(); break; case 'highlight': effect = UIHoverHighlightEffect.effect(); break; case 'lift': effect = UIHoverLiftEffect.effect(); break; } let shape; switch (options.shape) { case 'circle': shape = UIShape.circleShape; break; case 'rect': if (options.shapeCornerRadius) { shape = UIShape.rectShapeWithCornerRadius(options.shapeCornerRadius); } else { shape = UIShape.rectShape; } break; } return UIHoverStyle.styleWithEffectShape(effect, shape); }; if (!TouchManager.visionHoverStyleCache['default']) { const defaultOptions = TouchManager.visionHoverOptions['default']; TouchManager.visionHoverStyleCache['default'] = createHoverStyleFromOptions(defaultOptions || { effect: 'automatic', }); } if (view.visionHoverStyle) { if (typeof view.visionHoverStyle === 'string') { view.ios.hoverStyle = TouchManager.visionHoverStyleCache[view.visionHoverStyle] || TouchManager.visionHoverStyleCache['default']; } } else { view.ios.hoverStyle = TouchManager.visionHoverStyleCache['default']; } } } } export let TouchControlHandler; ensureTouchControlHandlers(); function ensureTouchControlHandlers() { if (__APPLE__) { var TouchHandlerImpl = /** @class */ (function (_super) { __extends(TouchHandlerImpl, _super); function TouchHandlerImpl() { return _super !== null && _super.apply(this, arguments) || this; } TouchHandlerImpl.initWithOwner = function (owner) { var handler = TouchHandlerImpl.new(); handler._owner = owner; return handler; }; TouchHandlerImpl.prototype.touchDown = function (args) { var _a, _b, _c, _d; (_b = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref) === null || _b === void 0 ? void 0 : _b.call(_a).notify({ eventName: GestureEvents.touchDown, object: (_d = (_c = this._owner) === null || _c === void 0 ? void 0 : _c.deref) === null || _d === void 0 ? void 0 : _d.call(_c), data: args, }); }; TouchHandlerImpl.prototype.touchUp = function (args) { var _a, _b, _c, _d; (_b = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref) === null || _b === void 0 ? void 0 : _b.call(_a).notify({ eventName: GestureEvents.touchUp, object: (_d = (_c = this._owner) === null || _c === void 0 ? void 0 : _c.deref) === null || _d === void 0 ? void 0 : _d.call(_c), data: args, }); }; TouchHandlerImpl.ObjCExposedMethods = { touchDown: { returns: interop.types.void, params: [interop.types.id] }, touchUp: { returns: interop.types.void, params: [interop.types.id] }, }; return TouchHandlerImpl; }(NSObject)); TouchControlHandler = TouchHandlerImpl; } } //# sourceMappingURL=touch-manager.js.map