// Enum available loco mode var LOCO_MODE = { ANALOG: 0, // Analog mode is for old DC locomotives that use a variable voltage on the track to control speed. MARKLIN: 1, // Märklin mode is for old marklin analog AC (with relay dir) Märklin locomotives. DCC: 2 // DCC mode is for Digital Command Control, a standard for digital model railway control. }; var LOCO_DIR = { FORWARD: 0, // Forward direction BACKWARD: 1 // Backward direction }; var Loco = { Mode: LOCO_MODE.DCC, ID: 0, Speed: 0, Dir: LOCO_DIR.FORWARD, Scale: 1, // Example real loco speed is 45Kmh/max, so what are step (128 for digital to represent 0-200Kmh) per Kmh MaxSpeed: 100, // Max speed in DCC step (<129) to reach scale speed (e.g. 45Kmh) setMode: function(mode) { this.Mode = mode; }, setID: function(id) { this.ID = id; }, setSpeed: function(speed) { this.Speed = speed; setSpeed(speed); // Update the speedometer needle }, setDir: function(dir) { this.Dir = dir; } }; /** * Update the speedometer based on the slider value. The slider value is expected to be in the range 0-128, * when a value is received, it is converted to a speed in Kmh based on the loco's scale and max speed, * then the speedometer needle is updated accordingly. * * @param {int} value */ function updateSpeedometer(value) { Loco.setSpeed(parseInt(value)); } /** * Speed is expected to be in the range 0-200. This function maps it to an angle for the needle. * at 100Kmh, needle is vertical, it's length is 50px, and it rotates from -120deg (0 speed) to +120deg (max speed). * At speed=100, x2=150, y2=70 */ function setSpeed(speed) { // Clamp speed speed = Math.max(0, Math.min(200, speed)); // Map speed to angle: 0 = -120deg, 100 = 0deg, 200 = +120deg var angle = -120 + (speed / 200) * 240; var rad = angle * Math.PI / 180; var r = 50; // needle length var cx = 150, cy = 120; var x2 = cx + r * Math.sin(rad); // Use sin for x, cos for y to match SVG coordinate system var y2 = cy - r * Math.cos(rad); document.getElementById('needle').setAttribute('x2', x2); document.getElementById('needle').setAttribute('y2', y2); } // Example: set speed to 0 initially setSpeed(0);