🎮 Live Demo
Horizontal (X)
0.00
Vertical (Y)
0.00
Acceleration Vector
(0.00,
0.00)
0° UP
Ready
💻 Component Code
// HORIZONTAL ACCELEROMETER COMPONENT
// Usage: const xAccel = new HorizontalAccelerometer('knobId', 'trackId', 'valueId');
class HorizontalAccelerometer {
constructor(knobId, trackId, valueId) {
this.knob = document.getElementById(knobId);
this.track = document.getElementById(trackId);
this.valueDisplay = document.getElementById(valueId);
this.value = 0;
this.velocity = 0;
this.isDragging = false;
this.startX = 0;
this.startValue = 0;
this.init();
}
init() {
this.knob.addEventListener('mousedown', (e) => this.startDrag(e.clientX));
this.knob.addEventListener('touchstart', (e) => {
e.preventDefault();
this.startDrag(e.touches[0].clientX);
});
document.addEventListener('mousemove', (e) => {
if (this.isDragging) this.drag(e.clientX);
});
document.addEventListener('touchmove', (e) => {
if (this.isDragging && e.touches[0]) {
e.preventDefault();
this.drag(e.touches[0].clientX);
}
}, { passive: false });
document.addEventListener('mouseup', () => this.stopDrag());
document.addEventListener('touchend', () => this.stopDrag());
}
startDrag(clientX) {
this.isDragging = true;
this.startX = clientX;
this.startValue = this.value;
this.velocity = 0;
this.updateTrackColor();
}
drag(clientX) {
const delta = (clientX - this.startX) / 80;
this.value = Math.max(-1, Math.min(1, this.startValue + delta));
this.velocity = (this.value - this.startValue) * 0.3;
this.update();
}
stopDrag() {
this.isDragging = false;
this.updateTrackColor();
}
update() {
this.knob.style.left = `${85 + this.value * 80}px`;
this.valueDisplay.textContent = this.value.toFixed(2);
this.updateTrackColor();
}
updateTrackColor() {
const intensity = Math.abs(this.value);
const velocityIntensity = Math.abs(this.velocity);
if (this.isDragging) {
this.track.style.background = `rgba(0, 180, 216, ${0.3 + intensity * 0.4})`;
} else if (velocityIntensity > 0.05) {
this.track.style.background = `rgba(0, 180, 216, ${0.2 + velocityIntensity * 0.3})`;
} else {
this.track.style.background = `rgba(255, 255, 255, ${0.05 + intensity * 0.05})`;
}
}
updatePhysics() {
if (!this.isDragging) {
const springForce = -this.value * 0.2;
this.velocity += springForce;
this.velocity *= 0.9;
this.value += this.velocity * 0.1;
if (Math.abs(this.value) < 0.005 && Math.abs(this.velocity) < 0.005) {
this.value = this.velocity = 0;
}
this.update();
}
return this.value;
}
setValue(newValue) {
this.value = Math.max(-1, Math.min(1, newValue));
this.velocity = 0;
this.update();
}
}