UNPKG

@eroscripts/osr-emu

Version:

A web-based graphical emulator for open source strokers.

78 lines (65 loc) 2.54 kB
import { constrain, map } from './util.js'; const MIN_SMOOTH_INTERVAL = 3; // Minimum auto-smooth ramp interval for live commands (ms) const MAX_SMOOTH_INTERVAL = 100; // Maximum auto-smooth ramp interval for live commands (ms) /** * A class that emulates the behavior of an axis as coded on the OSR Firmware (v3.3) */ export default class Axis { name = ''; _startTime = 0; _startPosition = 5000; _targetTime = 0; _targetPosition = 5000; _minInterval = MAX_SMOOTH_INTERVAL; constructor(name: string) { this.name = name; } set(magnitude: number, ext?: 'S' | 'I', extMagnitude: number = 0) { const currentTime = performance.now(); magnitude = constrain(magnitude, 0, 9999); extMagnitude = constrain(extMagnitude, 0, 9999999); if (!extMagnitude || (ext !== 'S' && ext !== 'I')) { // Live command // Update auto-smooth regulator const lastInterval = currentTime - this._startTime; if (lastInterval > this._minInterval && this._minInterval < MAX_SMOOTH_INTERVAL) { this._minInterval += 1; } else if (lastInterval < this._minInterval && this._minInterval > MIN_SMOOTH_INTERVAL) { this._minInterval -= 1; } this._startPosition = this.getPosition(); this._targetTime = currentTime + this._minInterval; } else if (ext === 'S') { // Speed command const speed = extMagnitude / 100; // Interpret extMagntitude as units per 100 ms. this._startPosition = this.getPosition(); const distance = Math.abs(magnitude - this._startPosition); const duration = Math.floor(distance / speed); this._targetTime = currentTime + duration; } else if (ext === 'I') { // Interval command const duration = extMagnitude; // Interpret extMagnitude as the duration of the move in ms. this._startPosition = this.getPosition(); this._targetTime = currentTime + duration; } this._startTime = currentTime; this._targetPosition = magnitude; } getPosition() { let position; // 0 - 9999 const currentTime = performance.now(); if (currentTime > this._targetTime) { position = this._targetPosition; } else if (currentTime > this._startTime) { position = map(currentTime, this._startTime, this._targetTime, this._startPosition, this._targetPosition); } else { position = this._startPosition; } return constrain(position, 0, 9999); } }