/* global AFRAME */ if (typeof AFRAME === 'undefined') { throw new Error('Component attempted to register before AFRAME was available.'); } /** * Haptics component for A-Frame. */ AFRAME.registerComponent('haptics', { schema: { actuatorIndex: {default: 0}, dur: {default: 100}, enabled: {default: true}, events: {type: 'array'}, eventsFrom: {type: 'string'}, force: {default: 1} }, multiple: true, init: function () { var self = this; this.callPulse = function () { self.pulse(); }; this._eventsFrom = null; var doInit = function () { var xrSession = self.el.sceneEl.xrSession; var controllers = xrSession && xrSession.inputSources; if (!controllers || !controllers.length) { return; } var trackedControls = self.el.components['tracked-controls']; if (!trackedControls) { return; } var controller = AFRAME.utils.trackedControls.findMatchingControllerWebXR( controllers, trackedControls.data.id, trackedControls.data.hand, trackedControls.data.controller, trackedControls.data.iterateControllerProfiles, trackedControls.data.handTrackingEnabled ); if (!controller) { return; } trackedControls.controller = controller; self.gamepad = controller.gamepad; if (!self.gamepad || !self.gamepad.hapticActuators || !self.gamepad.hapticActuators.length) { return; } self.addEventListeners(); }; if (this.el.components['tracked-controls'] && this.el.components['tracked-controls'].controller) { doInit(); } else { this.el.addEventListener('controllerconnected', function init () { doInit(); }); } }, remove: function () { this.removeEventListeners(); }, pulse: function (force, dur) { var actuator; var data = this.data; if (!data.enabled || !this.gamepad || !this.gamepad.hapticActuators) { return; } actuator = this.gamepad.hapticActuators[data.actuatorIndex]; actuator.pulse(force || data.force, dur || data.dur); }, addEventListeners: function () { var data = this.data; var i; var listenTarget; listenTarget = data.eventsFrom ? document.querySelector(data.eventsFrom) : this.el; if (!listenTarget) { return; } this._eventsFrom = listenTarget; for (i = 0; i < data.events.length; i++) { listenTarget.addEventListener(data.events[i], this.callPulse); } }, removeEventListeners: function () { var data = this.data; var i; var listenTarget; listenTarget = this._eventsFrom; if (!listenTarget) { listenTarget = data.eventsFrom ? document.querySelector(data.eventsFrom) : this.el; } if (!listenTarget) { return; } for (i = 0; i < data.events.length; i++) { listenTarget.removeEventListener(data.events[i], this.callPulse); } this._eventsFrom = null; } });