Referencias
El paquete tact-js proporciona funciones para controlar los dispositivos hápticos de bHaptics desde JavaScript. Permite reproducir patrones hápticos, controlar directamente los motores del dispositivo y gestionar la reproducción háptica.
import Tact from "tact-js";
Reproducción de háptica basada en eventos
Reproduce patrones hápticos vinculados a eventos específicos (diseñados en bHaptics Designer/Portal). Estas son las funciones recomendadas para la mayoría de las aplicaciones.
play
play({ eventKey, startTime, intensityRatio, durationRatio, offsetX, offsetY, deviceIndex }: PlayParams): Promise<void>;
type PlayParams = {
eventKey: string; // Name of the haptic event
startTime?: number; // Playback start position in milliseconds
intensityRatio?: number; // Intensity multiplier [0.0 - 2.0]
durationRatio?: number; // Duration multiplier
offsetX?: number; // Rotation offset [0.0 - 360.0]
offsetY?: number; // Vertical offset [-0.5 - 0.5]
deviceIndex?: number; // Target device index
};
Reproduce el evento háptico predefinido.
Parámetros
eventKey: Nombre del evento háptico.startTime(opcional): Posición de inicio de la reproducción en milisegundos — se omiten los primerosstartTimemilisegundos del evento. Por ejemplo, reproducir un evento de 3.260 ms constartTime: 2000solo reproduce los últimos 1.260 ms. (Predeterminado:0)intensityRatio(opcional): Multiplicador de la Intensity háptica. El rango válido es: [0.0-2.0] (Predeterminado:1.0)durationRatio(opcional): Multiplicador de la Duration. (Predeterminado:1.0)offsetX(opcional): Rota la háptica en sentido antihorario. El rango válido es: [0.0-360.0] (Predeterminado:0.0)offsetY(opcional): Mueve la háptica hacia arriba o hacia abajo. El rango válido es: [-0.5-0.5] (Predeterminado:0.0)deviceIndex(opcional): Índice del dispositivo de destino cuando hay varios dispositivos del mismo tipo de posición conectados. (Predeterminado:-1, sin dispositivo específico)
Devuelve
La promesa se resuelve sin valor (undefined) una vez que se envía la solicitud a bHaptics Player.
Tenga en cuenta que también se resuelve normalmente cuando la clave de evento no está registrada — en ese caso no se reproduce nada y no se lanza ningún error. Use getEvent para comprobar si existe una clave de evento.
Ejemplo
import Tact from "tact-js";
const playExample = async () => {
await Tact.play({ eventKey: "heartbeat" });
};
const playMoreExample = async () => {
await Tact.play({
eventKey: "hit",
startTime: 0,
intensityRatio: 1.0,
durationRatio: 1.0,
offsetX: 180.0,
offsetY: 0.25,
});
};
playLoop
playLoop({ eventKey, intensityRatio, durationRatio, interval, maxCount, offsetX, offsetY, deviceIndex }: PlayLoopParams): Promise<number>;
type PlayLoopParams = {
eventKey: string; // Name of the haptic event
intensityRatio?: number; // Intensity multiplier [0.0 - 2.0]
durationRatio?: number; // Duration multiplier
interval: number; // Pause between repetitions (milliseconds)
maxCount: number; // Total number of plays
offsetX: number; // Rotation offset [0.0 - 360.0]
offsetY: number; // Vertical offset [-0.5 - 0.5]
deviceIndex?: number; // Target device index
};
Reproduce el evento háptico en bucle el número de veces especificado.
Parámetros
eventKey: Nombre del evento háptico.intensityRatio(opcional): Multiplicador de la Intensity háptica. El rango válido es: [0.0-2.0] (Predeterminado:1.0)durationRatio(opcional): Multiplicador de la Duration. (Predeterminado:1.0)interval: Pausa entre repeticiones en milisegundos, medida desde el final de una reproducción hasta el inicio de la siguiente. Por ejemplo, un evento de 460 ms coninterval: 500ymaxCount: 3finaliza tras aproximadamente 2.380 ms (460 + 500 + 460 + 500 + 460).maxCount: Número total de veces que se reproduce el evento háptico, incluida la primera reproducción. Los valores menores que1se comportan como1.offsetX: Rota la háptica en sentido antihorario. El rango válido es: [0.0-360.0] (Predeterminado:0.0)offsetY: Mueve la háptica hacia arriba o hacia abajo. El rango válido es: [-0.5-0.5] (Predeterminado:0.0)deviceIndex(opcional): Índice del dispositivo de destino cuando hay varios dispositivos del mismo tipo de posición conectados. (Predeterminado:-1, sin dispositivo específico)
Devuelve
ID de solicitud que identifica esta solicitud de reproducción.
Tenga en cuenta que se devuelve un ID de solicitud incluso cuando la clave de evento no está registrada — en ese caso no se reproduce nada. Para detener un evento en bucle, use stop con la clave de evento o stopAll.
Mientras el bucle está en ejecución, isPlayingByEventKey devuelve true durante todo el intervalo, incluidas las pausas interval entre repeticiones.
Ejemplo
import Tact from "tact-js";
const playLoopExample = async () => {
const requestId = await Tact.playLoop({
eventKey: "hit",
intensityRatio: 1.0,
durationRatio: 1.0,
interval: 1000,
maxCount: 5,
offsetX: 0.0,
offsetY: 0.0,
});
console.log(`Playback request ID: ${requestId}`);
};
Reproducción directa de háptica
Si desea reproducir háptica sin eventos, use estas funciones.
playDot
playDot({ position, motorValues, duration, deviceIndex }: PlayDotParams): Promise<number>;
type PlayDotParams = {
position: PositionType; // Device position type
motorValues: number[]; // Array of motor intensity values [0 - 100]
duration?: number; // Duration in milliseconds
deviceIndex?: number; // Target device index
};
Reproduce retroalimentación háptica en los actuadores hápticos específicos.
Parámetros
position: Tipo de dispositivo háptico a reproducir. Consulte el enumPositionType.motorValues: Array de valores de Intensity para cada motor. La longitud del array debe coincidir con el número de motores del dispositivo. Cada valor debe ser un entero y estar dentro del rango. El rango válido es: [0-100].duration(opcional): Duration de la retroalimentación háptica en milisegundos. Se recomienda un valor mayor o igual a100.deviceIndex(opcional): Índice del dispositivo de destino cuando hay varios dispositivos del mismo tipo de posición conectados. (Predeterminado:-1, sin dispositivo específico)
Devuelve
ID de solicitud que identifica esta solicitud de reproducción. Para detener la reproducción, use stopAll.
Tenga en cuenta que los parámetros no se validan en el lado del cliente — se devuelve un ID de solicitud incluso cuando, por ejemplo, motorValues tiene una longitud incorrecta o contiene valores fuera de rango; en ese caso es posible que la háptica simplemente no se reproduzca.
Ejemplo
import Tact, { PositionType } from "tact-js";
const playDotExample = async () => {
const requestId = await Tact.playDot({
position: PositionType.ForearmL, // Left TactSleeve
motorValues: [100, 80, 60], // TactSleeve has 3 motors
duration: 100
});
console.log(`Playback request ID: ${requestId}`);
}
playPath
playPath({ position, x, y, intensity, duration, deviceIndex }: PlayPathParams): Promise<number>;
type PlayPathParams = {
position: PositionType; // Device position type
x: number[]; // Array of x coordinates [0.0 - 1.0]
y: number[]; // Array of y coordinates [0.0 - 1.0]
intensity: number[]; // Array of intensity values [0 - 100]
duration?: number; // Duration in milliseconds
deviceIndex?: number; // Target device index
};
Reproduce retroalimentación háptica a lo largo de las coordenadas especificadas. A diferencia de playDot, que controla motores individuales, este método especifica la Intensity háptica para coordenadas concretas del dispositivo.
Al especificar la posición háptica, playDot ofrece un control discreto, mientras que playPath es más continuo. playDot asigna Intensity a actuadores individuales, mientras que playPath permite especificar la Intensity para coordenadas concretas (entre 0 y 1 tanto para el eje X como para el Y), haciendo que los actuadores cercanos vibren en consecuencia.
Puede especificar varias coordenadas con varias intensidades. Tenga en cuenta que todos los actuadores alrededor de estas coordenadas de la lista se activarán simultáneamente, no de forma secuencial. El tamaño de todos los arrays (x, y e intensity) debe ser el mismo.
Si los arrays x, y e intensity tienen longitudes distintas, el módulo WebAssembly interno del SDK se bloquea con un error irrecuperable (verificado en tact-js 2.0.4) — la háptica deja de funcionar hasta que se recarga la página. Asegúrese siempre de que los tres arrays tienen la misma longitud antes de llamar a esta función.
Si llama continuamente a esta función cambiando los valores de forma gradual, puede lograr el efecto de un punto háptico en movimiento.

Parámetros
position: Tipo de dispositivo háptico a reproducir. Consulte el enumPositionType.x: Array de coordenadas X del efecto háptico. Cada valor debe estar dentro del rango: [0.0-1.0]y: Array de coordenadas Y del efecto háptico. Cada valor debe estar dentro del rango: [0.0-1.0]intensity: Array de valores de Intensity para cada coordenada. Cada valor debe ser un entero y estar dentro del rango: [0-100]duration(opcional): Duration de la retroalimentación háptica en milisegundos. Se recomienda un valor mayor o igual a100.deviceIndex(opcional): Índice del dispositivo de destino cuando hay varios dispositivos del mismo tipo de posición conectados. (Predeterminado:-1, sin dispositivo específico)
Devuelve
ID de solicitud que identifica esta solicitud de reproducción. Para detener la reproducción, use stopAll.
Ejemplo
import Tact, { PositionType } from "tact-js";
const HAPTIC_PATHS = [
{
x: [0.738, 0.723, 0.709, 0.696, 0.682, 0.667, 0.653],
y: [0.680, 0.715, 0.749, 0.782, 0.816, 0.852, 0.885],
intensity: 20
},
{
x: [0.061, 0.072, 0.102, 0.184, 0.254, 0.310, 0.363],
y: [0.632, 0.587, 0.542, 0.498, 0.411, 0.366, 0.301],
intensity: 60
}
];
const TIME_OF_FRAME = 250; // milliseconds
const playPathExample = async () => {
const frames = HAPTIC_PATHS[0].x.length;
for (let i = 0; i < frames; i++) {
await Tact.playPath({
position: PositionType.Vest, // TactSuit Pro
x: HAPTIC_PATHS.map(point => point.x[i]),
y: HAPTIC_PATHS.map(point => point.y[i]),
intensity: HAPTIC_PATHS.map(point => point.intensity),
duration: TIME_OF_FRAME
});
await new Promise(resolve => setTimeout(resolve, TIME_OF_FRAME));
}
}
playGlove
playGlove({ position, motors, playtimes, shapes, repeatCount }: PlayGloveParams): Promise<number>;
type PlayGloveParams = {
position: PositionType; // GloveL or GloveR
motors: Int32Array; // Array of 8 motor intensity values [0 - 100]
playtimes: Int32Array; // Array of 8 time interval values
shapes: Int32Array; // Array of 8 waveform values
repeatCount: number; // Number of times to play the pattern
};
Solo TactGlove. Reproduce háptica en TactGlove con un control preciso de los patrones de Duration e Intensity. Esto proporciona un control más detallado en comparación con playDot.
Cada parámetro de array debe contener exactamente ocho elementos, uno por cada motor del guante.
Parámetros
-
position: Tipo de dispositivo háptico a reproducir. Debe usarPositionType.GloveLoPositionType.GloveR. -
motors: Array de 8 valores de Intensity, uno por motor. Cada valor debe ser un entero y estar dentro del rango: [0-100]Índice del array El motor está ubicado en… 0Punta del pulgar 1Punta del índice 2Punta del dedo medio 3Punta del dedo anular 4Punta del meñique 5En la muñeca 6En la palma (lado del pulgar) 7En la palma (lado del meñique) -
playtimes: Array de 8 valores de intervalo de tiempo. Los valores válidos son:Valor Duration 15ms 210ms 420ms 630ms 840ms -
shapes: Array de 8 valores de forma de onda que controlan cómo cambia la Intensity con el tiempo:Valor Patrón de forma de onda 0Intensity constante durante la Duration 1Comienza en la Intensity especificada y disminuye a la mitad 2Comienza a media Intensity y aumenta hasta la Intensity máxima -
repeatCount: Número total de veces que se reproduce el patrón de 8 motores, incluida la primera reproducción.
Devuelve
ID de solicitud que identifica esta solicitud de reproducción. Para detener la reproducción, use stopAll.
Ejemplo
import Tact, { PositionType } from "tact-js";
const playGloveExample = async () => {
const motors = new Int32Array([100, 100, 100, 100, 100, 100, 100, 100]);
const playtimes = new Int32Array([8, 8, 8, 8, 8, 8, 8, 8]);
const shapes = new Int32Array([2, 2, 2, 2, 2, 2, 2, 2]);
const requestId = await Tact.playGlove({
position: PositionType.GloveR,
motors,
playtimes,
shapes,
repeatCount: 3
});
console.log(`Playback request ID: ${requestId}`);
}
Control de reproducción
pause
pause(eventKey: string): Promise<void>
Pausa un evento háptico específico que se está reproduciendo actualmente.
Parámetros
eventKey: Nombre del evento háptico a pausar.
Ejemplo
import Tact from "tact-js";
const playAndPauseExample = async () => {
await Tact.play({ eventKey: "dash" });
await new Promise(resolve => setTimeout(resolve, 1000));
await Tact.pause("dash");
}
resume
resume(eventKey: string): Promise<void>
Reanuda un evento háptico pausado previamente.
Parámetros
eventKey: Nombre del evento háptico a reanudar.
Ejemplo
import Tact from "tact-js";
const playPauseAndResumeExample = async () => {
await Tact.play({ eventKey: "dash" });
await new Promise(resolve => setTimeout(resolve, 1000));
await Tact.pause("dash");
await new Promise(resolve => setTimeout(resolve, 1000));
await Tact.resume("dash");
}
stop
stop(eventKey: string): Promise<void>
Detiene por completo un evento háptico específico.
Parámetros
eventKey: Nombre del evento háptico a detener.
Ejemplo
import Tact from "tact-js";
const stopExample = async () => {
await Tact.play({ eventKey: "dash" });
await new Promise(resolve => setTimeout(resolve, 1000));
await Tact.stop("dash");
}
stopAll
stopAll(): Promise<void>
Detiene toda la háptica que se está reproduciendo actualmente.
Ejemplo
import Tact from "tact-js";
const stopAllExample = async () => {
await Tact.play({ eventKey: "dash" });
await Tact.play({ eventKey: "heartbeat" });
await Tact.play({ eventKey: "hit" });
await Tact.play({ eventKey: "slash" });
await new Promise(resolve => setTimeout(resolve, 500));
await Tact.stopAll();
}
Ciclo de vida
init
init({ appId, apiKey }: InitParams): Promise<boolean>;
type InitParams = {
appId: string; // Your bHaptics App ID
apiKey: string; // Your bHaptics API Key
};
Inicializa el SDK de bHaptics. Esta función debe llamarse antes de usar cualquier otra función del SDK. Inicializa el SDK y establece la conexión con bHaptics Player.
Parámetros
appId: El ID de su aplicación de bHaptics obtenido del bHaptics Developer PortalapiKey: Su API key de bHaptics obtenida del bHaptics Developer Portal
Devuelve
Devuelve true si la inicialización es correcta, false en caso contrario.
Ejemplo
import Tact from "tact-js";
const initTact = async () => {
const result = await Tact.init({
appId: "your-app-id",
apiKey: "your-api-key",
});
console.log(result ? "Connection Success!" : "Connection Failed...");
}
Comprobación de estado
getConnectedDevices
getConnectedDevices(): Promise<any[]>
Obtiene una lista de todos los dispositivos hápticos conectados.
Devuelve
Array de objetos de dispositivo conectado. Devuelve un array vacío ([]) cuando no hay dispositivos conectados. Cada objeto tiene los siguientes campos:
| Campo | Tipo | Descripción |
|---|---|---|
position | number | Posición numérica del dispositivo: 0 Vest, 1 ForearmL, 2 ForearmR, 3 Head, 4 HandL, 5 HandR, 6 FootL, 7 FootR, 8 GloveL, 9 GloveR. Use PositionUtils.positionToType(position) para convertirlo a PositionType. |
deviceName | string | Nombre del dispositivo (p. ej. "TactGlove (L)"). |
address | string | Dirección MAC del dispositivo. Úsela con ping. |
connected | boolean | Indica si el dispositivo está conectado actualmente. |
paired | boolean | Indica si el dispositivo está emparejado en bHaptics Player. |
battery | number | Nivel de batería en porcentaje. |
audioJackIn | boolean | Indica si hay un jack de audio conectado (dispositivos con accesorio de audio). |
vsm | number | Configuración de intensidad de vibración configurada en bHaptics Player. |
El ejemplo del valor de retorno es el siguiente:
[
{
"position": 8,
"deviceName": "TactGlove (L)",
"address": "F418EB165E99",
"connected": true,
"paired": true,
"battery": 91,
"audioJackIn": false,
"vsm": 20
},
{
"position": 9,
"deviceName": "TactGlove (R)",
"address": "DF8B33412EC5",
"connected": true,
"paired": true,
"battery": 84,
"audioJackIn": false,
"vsm": 20
}
]
Ejemplo
import Tact from "tact-js";
const showDevicesExample = async () => {
const devices = await Tact.getConnectedDevices();
console.log("Connected devices:", devices);
}
getHapticMappings
getHapticMappings(): Promise<any[]>
Obtiene una lista de todos los eventos hápticos registrados en la aplicación háptica actual (desplegada desde el bHaptics Developer Portal).
Devuelve
Array de objetos de mapeo háptico. Cada objeto tiene los siguientes campos:
| Campo | Tipo | Descripción |
|---|---|---|
eventName | string | Clave del evento. Úsela con play y las demás funciones basadas en eventos. |
eventTime | number | Duration del evento en milisegundos. |
El ejemplo del valor de retorno es el siguiente:
[
{
"eventName": "punch-recoil",
"eventTime": 180
},
{
"eventName": "dash",
"eventTime": 3260
},
{
"eventName": "teleport",
"eventTime": 460
}
]
Ejemplo
import Tact from "tact-js";
const showMappingsExample = async () => {
const mappings = await Tact.getHapticMappings();
for (const mapping of mappings) {
console.log(`${mapping.eventName}: ${mapping.eventTime}ms`);
}
}
getEvent
getEvent(eventKey: string): Promise<number>
Obtiene la Duration de un evento háptico registrado.
Parámetros
eventKey: Nombre del evento háptico a consultar.
Devuelve
Duration del evento en milisegundos. Devuelve 0 si la clave de evento no está registrada — puede usarlo para comprobar si existe una clave de evento antes de llamar a play.
Ejemplo
import Tact from "tact-js";
const getEventExample = async () => {
const duration = await Tact.getEvent("dash");
if (duration > 0) {
console.log(`dash is ${duration}ms long`);
} else {
console.log("dash is not registered");
}
}
isDeviceConnected
isDeviceConnected(position: PositionType): Promise<boolean>
Comprueba si un tipo de dispositivo específico está conectado.
Parámetros
position: Tipo de dispositivo háptico a reproducir. Consulte el enumPositionType.
Devuelve
true si el tipo de dispositivo está conectado, false en caso contrario.
Ejemplo
import Tact, { PositionType } from "tact-js";
const isDeviceConnectedExample = async () => {
const isGloveConnected = await Tact.isDeviceConnected(PositionType.GloveR);
console.log("Right TactGlove connected:", isGloveConnected);
}
isConnected
isConnected(): Promise<boolean>
Comprueba el estado de conexión con bHaptics Player.
Devuelve
true si está conectado a bHaptics Player, false en caso contrario.
isPlaying
isPlaying(): Promise<boolean>
Comprueba si hay alguna retroalimentación háptica reproduciéndose actualmente.
Devuelve
true si hay alguna háptica reproduciéndose, false en caso contrario.
isPlayingByEventKey
isPlayingByEventKey(eventKey: string): Promise<boolean>
Comprueba si un evento háptico específico se está reproduciendo actualmente.
Parámetros
eventKey: Nombre del evento háptico a comprobar
Devuelve
true si el evento háptico especificado se está reproduciendo, false en caso contrario.
Control del dispositivo
ping
ping(address: string): Promise<void>
Envía una señal de ping a un dispositivo específico para probar la conexión.
Parámetros
address: La dirección MAC del dispositivo háptico. Puede obtener la dirección congetConnectedDevices()
Ejemplo
import Tact from "tact-js";
const pingFirstDeviceExample = async () => {
const devices = await Tact.getConnectedDevices();
if (devices.length > 0) {
await Tact.ping(devices[0].address);
}
}
pingAll
pingAll(): Promise<void>
Envía una señal de ping a todos los dispositivos conectados.
motorTest
motorTest(): Promise<void>
Ejecuta una secuencia de prueba de motores en el TactSuit Pro (Vest): cada una de las 32 posiciones de motor se activa a máxima Intensity durante un segundo, una tras otra. La secuencia completa tarda unos 32 segundos; la promesa devuelta se resuelve cuando la secuencia finaliza.
Tenga en cuenta que esta prueba cubre únicamente la posición Vest — no prueba otros tipos de dispositivo.
Enums comunes
PositionType
enum PositionType {
Vest = "Vest",
ForearmL = "ForearmL",
ForearmR = "ForearmR",
Head = "Head",
HandL = "HandL",
HandR = "HandR",
FootL = "FootL",
FootR = "FootR",
GloveL = "GloveL",
GloveR = "GloveR"
}
Enum de cadenas. Úselo para especificar el tipo de dispositivo háptico.
| Valor | Dispositivo | Número de motores |
|---|---|---|
Vest | TactSuit Pro | 32 |
ForearmL | TactSleeve(Left) | 3 |
ForearmR | TactSleeve(Right) | 3 |
Head | TactVisor | 4 |
HandL | Tactosy for Hands(Left) | 3 |
HandR | Tactosy for Hands(Right) | 3 |
FootL | Tactosy for Feet(Left) | 3 |
FootR | Tactosy for Feet(Right) | 3 |
GloveL | TactGlove(Left) | 8 |
GloveR | TactGlove(Right) | 8 |
tact-js también exporta una clase PositionUtils con helpers estáticos para convertir entre las posiciones numéricas usadas por getConnectedDevices y el enum PositionType:
import { PositionType, PositionUtils } from "tact-js";
PositionUtils.positionToType(9); // PositionType.GloveR
PositionUtils.enumToPosition(PositionType.Vest); // 0