From cdeb95a6b7384ae4ed1768e1b311cc3eab4158af Mon Sep 17 00:00:00 2001 From: "Michael J. Roberts" <84131395+michael-observerly@users.noreply.github.com> Date: Fri, 31 Dec 2021 06:30:30 +0000 Subject: [PATCH] feat(useVibrate): new function (#1082) Co-authored-by: Anthony Fu --- packages/core/useVibrate/index.md | 36 +++++++++++++ packages/core/useVibrate/index.ts | 85 +++++++++++++++++++++++++++++++ packages/functions.md | 1 + 3 files changed, 122 insertions(+) create mode 100644 packages/core/useVibrate/index.md create mode 100644 packages/core/useVibrate/index.ts diff --git a/packages/core/useVibrate/index.md b/packages/core/useVibrate/index.md new file mode 100644 index 00000000000..03f23cd722e --- /dev/null +++ b/packages/core/useVibrate/index.md @@ -0,0 +1,36 @@ +--- +category: Browser +--- + +# useVibrate + +Reactive vibration web API + +Most modern mobile devices include vibration hardware, which lets software +code provides physical feedback to the user by causing the device to shake. + +The Vibration API offers Web apps the ability to access this hardware, +if it exists, and does nothing if the device doesn't support it. + +## Usage + +Vibration is described as a pattern of on-off pulses, which may be of varying +lengths. + +The pattern may consist of either a single integer describing the +number of milliseconds to vibrate, or an array of integers describing +a pattern of vibrations and pauses. + +```ts +import { useVibrate } from '@vueuse/core' + +// This vibrates the device for 300 ms +// then pauses for 100 ms before vibrating the device again for another 300 ms: +const { vibrate, stop, isSupported } = useVibrate({ pattern: [300, 100, 300] }) + +// Start the vibration, it will automatically stop when the pattern is complete: +vibrate() + +// But if you want to stop it, you can: +stop() +``` diff --git a/packages/core/useVibrate/index.ts b/packages/core/useVibrate/index.ts new file mode 100644 index 00000000000..6b410f0e6b4 --- /dev/null +++ b/packages/core/useVibrate/index.ts @@ -0,0 +1,85 @@ +import { ref } from 'vue-demi' +import type { MaybeRef, Pausable } from '@vueuse/shared' +import { useIntervalFn } from '@vueuse/shared' +import type { ConfigurableNavigator } from '../_configurable' +import { defaultNavigator } from '../_configurable' + +export interface UseVibrateOptions extends ConfigurableNavigator { + /** + * + * Vibration Pattern + * + * An array of values describes alternating periods in which the + * device is vibrating and not vibrating. Each value in the array + * is converted to an integer, then interpreted alternately as + * the number of milliseconds the device should vibrate and the + * number of milliseconds it should not be vibrating + * + * @default [] + * + */ + pattern?: MaybeRef + /** + * Interval to run a persistent vibration, in ms + * + * Pass `0` to disable + * + * @default 0 + * + */ + interval?: number +} + +/** + * Reactive vibrate + * + * @see https://vueuse.org/useVibrate + * @see https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API + * @param options + */ +export function useVibrate(options?: UseVibrateOptions) { + const { + pattern = [], + interval = 0, + navigator = defaultNavigator, + } = options || {} + + const isSupported = typeof navigator !== 'undefined' && 'vibrate' in navigator + + const patternRef = ref(pattern) + let intervalControls: Pausable | undefined + + const vibrate = (pattern = patternRef.value) => { + if (isSupported) + navigator.vibrate(pattern) + } + + // Attempt to stop the vibration: + const stop = () => { + // Stope the vibration if we need to: + if (isSupported) + navigator.vibrate(0) + intervalControls?.pause() + } + + if (interval > 0) { + intervalControls = useIntervalFn( + vibrate, + interval, + { + immediate: false, + immediateCallback: false, + }, + ) + } + + return { + isSupported, + pattern, + intervalControls, + vibrate, + stop, + } +} + +export type UseVibrateReturn = ReturnType diff --git a/packages/functions.md b/packages/functions.md index 611c7f3246e..2af4987dda3 100644 --- a/packages/functions.md +++ b/packages/functions.md @@ -43,6 +43,7 @@ - [`useTitle`](https://vueuse.org/core/useTitle/) — reactive document title - [`useUrlSearchParams`](https://vueuse.org/core/useUrlSearchParams/) — reactive [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) - [`useWakeLock`](https://vueuse.org/core/useWakeLock/) — reactive [Screen Wake Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API) provides a way to prevent devices from dimming or locking the screen when an application needs to keep running + - [`useVibrate`](https://vueuse.org/core/useVibrate/) — reactive vibration of the user's device [Vibration API](https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API) ### Component - [`computedInject`](https://vueuse.org/core/computedInject/) — combine computed and inject