HangarControl Touch Panel
1. Overview
The HangarControl Touch Panel turns any device with a web browser into a fully interactive flight simulator control surface. Tablets, phones, old laptops, touchscreen monitors, or even a second browser window on your main PC. If it can open a web page, it can be a panel.
You design the layout in HangarControl's visual designer, placing buttons, gauges, displays, images, and templates anywhere on a free-placement canvas. The panel runs as a local web server. Open the URL in a browser and you have a live, interactive panel that communicates with your simulator in real time.
You have two ways to view a panel. Open it in any web browser on any device, which is ideal for tablets and phones over your network. Or, on the PC running HangarControl, open it as a native local window — a clean, borderless window with no browser chrome that you can place on any monitor. See the Local Window section for the native option.
How It Works
- You create and design a panel in HangarControl's Touch Panel Designer.
- When the panel is enabled, HangarControl starts a local HTTP server on the configured port.
- You open the panel URL in any web browser (on the same PC or any device on your network).
- The browser connects to HangarControl via WebSocket for real-time communication.
- When you press a button on the panel, the browser sends the action to HangarControl, which executes it (fires SimConnect events, writes LVars, sends keyboard shortcuts, etc.).
- HangarControl continuously pushes live simulator data back to the browser, updating gauges, displays, and button states in real time.
What You Need
- HangarControl installed and running (trial or full license).
- A web browser on any device. Chrome, Edge, Firefox, and Safari all work.
- A simulator connected through HangarControl (MSFS, DCS, X-Plane).
2. Getting Started
Opening the Designer
From the HangarControl main window, open the profile you want to add panels to. Click the Touch Panel button in the sidebar or header area to open the Touch Panel Designer window.
Creating a Panel
In the panel list on the left side of the designer, click the + button. A new panel named "Touch Panel 1" is created with a single blank page.
In the toolbar at the top, set the panel's properties:
- Name — Give it a descriptive name (e.g., "Overhead Panel", "Radio Stack").
- W / H — Canvas dimensions in pixels. Default is 1024 x 600. Match this to your target device's screen resolution for best results.
- Port — The HTTP port the panel will run on. Default is 19860. Each panel needs a unique port.
- BG — Background color in hex (default
#0D0D0D).
Enabling a Panel
Check the Enabled checkbox in the toolbar. This starts the local web server on the configured port. You will see a connection status indicator update in the designer.
Viewing in Browser
Click the Open in Browser button in the toolbar. Your default browser will open to http://localhost:19860 (or whatever port you configured). You should see your panel with any widgets you have placed.
To access the panel from another device on your network (tablet, phone), use your PC's local IP address instead of localhost. For example: http://192.168.1.100:19860. See the Networking & Access section for details on LAN setup.
The browser tab takes the panel's own name, so several panels open across several tabs can be told apart at a glance. There is nothing to configure, and renaming a panel updates any tab already showing it.
Opening as a Local Window
If you want the panel on the same PC without a browser, click Open Window in the toolbar instead of Open in Browser. The panel opens as its own borderless native window on the screen you have selected. This is the best option for a dedicated touchscreen or a spare monitor on your sim rig. Full details are in the Local Window section.
Once open, the window stays where you put it. Stopping and starting services, switching profiles, and running LAN setup all leave it alone, and it reconnects on its own when the service comes back, so you are not repositioning it every time. It closes when you close it, when its panel is deleted or disabled, or when HangarControl exits.
3. The Designer
The Touch Panel Designer is where you build your panel layout. It is a visual drag-and-drop editor with a live preview canvas.
Toolbar Settings
The toolbar runs across the top of the designer window and contains all global panel settings:
| Setting | Description |
|---|---|
| Name | Panel display name (shown in the browser header if enabled). |
| W / H | Canvas width and height in pixels. Changes take effect immediately. |
| Port | HTTP server port. Each panel must have a unique port. |
| BG | Canvas background color (hex). Default: #0D0D0D. |
| Margin | Padding around the canvas in the browser view (pixels). |
| Rows / Cols | Grid overlay dimensions for visual alignment. |
| Enabled | Starts or stops the panel's web server. |
| Header | Header bar preference (panel name, page navigation arrows, and connection status). Each browser also has its own Header toggle in the on-screen Settings menu, and that per-device choice is what the browser actually uses. |
| Footer | Footer bar preference. Like the header, each browser has its own toggle in the on-screen Settings menu. |
| Zone Following | Engaging a Target Zone automatically releases every other engaged zone, so only one is ever active at a time. Applies instantly to every connected browser and local window with no reconnect or Save. |
| Grid | Show/hide the grid overlay on the canvas. |
| Snap | Snap widgets to grid intersections when dragging. |
| Lock Aspect | Maintain the aspect ratio while resizing any widget in the designer. Useful for gauges, web views, and images that have a natural shape. |
| Refocus | After a touch, return focus to this application (for local touchscreen setups). |
| Auto Browser | When checked, this panel opens automatically in your default browser whenever its profile is selected. |
| Auto Window | When checked, this panel opens automatically as a native local window whenever its profile is selected. |
| Screen | Which monitor the native local window opens on. The list shows each connected display with its resolution. |
| Open in Browser | Enables the panel and opens it in your default browser. |
| Open Window | Enables the panel and opens it as a native local window on the selected screen. |
| − / % / + / Fit | Zoom controls. Zoom in or out on the canvas, or click Fit to scale the panel to the viewport. You can also Ctrl+scroll to zoom toward the cursor. |
Pages
Each panel can have multiple pages. Think of pages as separate screens you can switch between, like tabs. Only one page is visible in the browser at a time.
- The page bar sits below the toolbar. Click a page tab to switch to it.
- Click + to add a new page.
- Click − to remove the current page.
- Click Rename to change the current page's name.
- Click Copy to duplicate the current page. Every widget, layer, binding, and action comes across with fresh IDs, so the copy is completely independent of the original. The duplicate is inserted directly after the page you copied.
- Click ✎ Draw to add a Draw Overlay layer to the current page. See Layers for what those do.
You can create Button widgets with the Page Navigation action type to let users switch between pages from the browser. You can also use Next Panel and Previous Panel actions to cycle through panels.
Layers
Each page has one or more layers. Layers control the z-order (stacking) of widgets, and give you tools for locking and hiding groups of widgets while you work on others.
- The layer bar sits below the page bar. Click a layer tab to make it the active (target) layer.
- Click + to add a new layer, − to remove the active one, and Rename to rename it.
- Click Copy To… to copy the active layer and all its widgets to another page, to all other pages, or to a page on a different panel, keeping the exact positions. When the target panel has a different canvas size, you choose whether to scale the layer to fit or keep the original positions.
- Use ▲ and ▼ to move the active layer up or down the stack. The label at the end of the layer bar shows the active layer's z-index.
- Each layer tab carries its own eye toggle for visibility and a small color swatch that sets a designer-only background for that layer. The swatch is purely a working aid and is never sent to the browser, so you can tint a layer to keep track of it while you build without changing what your panel looks like.
- Each layer has an opacity control (the − and + either side of the percentage). This one does carry through to the browser, so you can fade a background layer back behind your controls.
- Locking a layer prevents accidental selection or movement of its widgets in the designer.
- Click the ⚡ button to set a Layer Condition on the active layer. When a condition is set, the layer is only visible at runtime when the condition is true. Conditions can reference LVars (
L:XMLVAR_...), SimVars (A:LIGHT PANEL), HC Variables (HC:MyMode), Flags (FLAG:NightMode:Set), or DCS cockpit arguments and telemetry (DCS:404,DCS:GEAR) — there is a DCS... browse button in the condition dialog for those. Operators are==,!=,>,<,>=, and<=. A lightning bolt icon appears next to layers that have a condition.
When you add a new widget, it is placed on the currently active layer. You can change a widget's layer later in the edit dialog.
Draw Overlay Layers
A Draw Overlay layer is a live drawing surface, not a decoration layer. Add one with the ✎ Draw button on the page bar, and the browser gets a full-canvas scribble pad on that layer plus a drawing toolbar that slides up from the bottom of the screen.
The toolbar gives you six pen colors, three pen sizes, Undo to remove the last stroke, and Clear to wipe the layer. Tap the small handle to collapse the toolbar down to a thin bar so it stays out of the way, and that collapsed state is remembered on the device. Strokes are kept per layer, so two Draw Overlay layers on the same page keep their drawings separate.
Because the layer sits in the normal z-order, you can put a Draw Overlay above a background image, above a template, or above your buttons, whichever you need. The toolbar only appears when the current page actually has a Draw Overlay layer on it.
Canvas & Grid
The center of the designer is the canvas. It represents the browser viewport at the dimensions you configured (W x H). A visible accent border marks the exact edges of the panel so the boundaries are always obvious regardless of background color. Widgets appear here and can be dragged and resized.
- Click a widget to select it. Ctrl+click to add or remove widgets from a multi-selection.
- Drag a widget to reposition it. When multiple widgets are selected, dragging moves them all together.
- Resize by grabbing the edge or corner handles on a selected widget. Resize handles only appear when a single widget is selected.
- Double-click a widget to open the edit dialog. You do not have to — simply selecting a widget puts its full editor in the properties pane on the right, which is usually faster.
- Zoom with Ctrl+scroll (tracks cursor position), or use the − / + / Fit buttons in the toolbar.
- Pan by middle-mouse dragging when zoomed in. Scrollbars also appear automatically.
- Enable Grid and Snap in the toolbar for precise alignment.
Right-Click Menu
Right-click anywhere on the canvas to open the context menu. From here you can add new widgets:
- Add Button — Creates a new button widget.
- Add Gauge — Creates a gauge widget (select a gauge from the library in the edit dialog).
- Add Display — Creates a display widget for showing live sim values.
- Add Label — Creates a text label (no interaction, just text).
- Add Image... — Opens a file picker to import an image file.
- Add Web View — Creates a Web View widget that embeds a web page or live browser-based panel.
- Add Slider — Creates a Slider or Touch Zone widget.
- Add Target Zone — Creates a Target Zone that hands physical hardware to a spot on your panel.
- Add Transparent Zone — Creates a real see-through hole for local window overlays.
- Add Template... — Opens the template picker to select a built-in HTML template.
- Paste Widget — Pastes a previously copied widget.
Right-click on a widget to get widget-specific options: Edit Widget, Copy, Duplicate, Fit to Canvas, the size presets (Size to Grid Cell, 2x1, 1x2, 2x2, 3x3), and Delete. When multiple widgets are selected, Duplicate and Delete apply to the entire selection (the menu shows the count, e.g., "Duplicate (3)").
4. Widget Types
Every element on your panel is a widget. Each widget type serves a different purpose.
Button
The most common widget type. Buttons fire actions when pressed in the browser. They can display a label, an icon, a live value, or all three. Buttons support the full range of press types (short, long, hold, release, double-tap) and all action types.
Display
Similar to a button, but intended for displaying live simulator data. Displays can show a label, a live value (e.g., current heading, altitude, COM frequency), and can also fire actions on press. Use Displays when the primary purpose is to show information rather than trigger an action.
Gauge
Gauges render interactive HTML instruments in an embedded iframe. HangarControl ships with a library of built-in gauges (airspeed, altimeter, heading, RPM, etc.) and you can import your own custom gauge HTML files. Gauges are driven by simulator variables through input bindings. See the Gauges section for details.
Label
A non-interactive text element. Labels are transparent by default and have no border or press behavior. Use them for section headings, descriptions, or annotations on your panel.
Spacer
An invisible placeholder. Spacers are completely hidden in the browser. They exist only to reserve space in the layout or serve as alignment guides in the designer.
Image
Displays a static image file. Images are imported from your computer and stored in HangarControl's asset folder. Images support fit modes (fill, contain, cover) and cropping. They are non-interactive by default. Use images for backgrounds, panel overlays, aircraft diagrams, or any visual element.
Web View
Embeds a live web page directly inside your panel through an iframe. Point it at any URL — an external instrument page, a browser-based panel from another tool, or a GlassOut viewer. The Web View renders and updates live, right alongside your other widgets. See the GlassOut Integration section for the most common use.
Slider / Touch Zone
A flexible drag widget. A Slider lets you drag along a track to drive a value; a Touch Zone is a draggable region you can lay over other content. Configure the orientation (horizontal or vertical), pixels per step, and invert direction.
Two modes are available. Stepped fires an increase action when dragged one way and a decrease action the other, so it behaves like an encoder. Continuous maps the drag position to a 0–100% axis and sends it to an axis target, which can be a SimConnect event, an LVar, a DCS axis, or an X-Plane DataRef.
A slider can also be told to drive the armed target instead of its own baked-in actions. Point it at a Selection Group and it drives whichever button in that group is currently armed, or leave the group empty and it drives whichever Target Zone is engaged. See Selection Groups.
The display style controls how it looks in the browser: Slider shows a visible track and handle, Zone shows a highlighted region, and Hidden shows nothing at all — a completely invisible touch target. Hidden zones are perfect for laying interactive areas over a background image or a GlassOut backdrop.
Target Zone
A Target Zone hands your physical hardware to a spot on the panel. Tap the zone to engage it, and the devices bound to that zone stop doing their normal job and start doing whatever the zone says instead. Tap it again to release, and everything goes back to normal.
This is what makes one encoder do the work of a dozen. Bind a Knobster dial, a MIDI knob, or any button on a joystick or panel to a zone, lay zones over a background image or a GlassOut display, and now that one knob adjusts whichever instrument you last touched. Zones support DirectInput buttons, Knobster controls, MIDI notes, and serial encoder tokens.
Add a Target Zone from the canvas right-click menu, then select it and configure it in the properties pane on the right:
- Label and Rotation — as with any widget.
- Shape — rectangle or circle. Circles are ideal over round knobs on a photo backdrop.
- When Not Engaged and When Engaged — each state independently controls whether the highlight fill, the border, and the label are shown, each with its own color. Turn everything off in both states and the zone becomes completely invisible while still working.
- Actions — the list of hardware bindings that fire only while the zone is engaged. Click + Add Action, then use the capture button and turn the knob or press the control you want. Each action records the device, the input, a direction (clockwise, counter-clockwise, or press), whether it fires on press or release, and the command to run.
If two zones are engaged and both bind the same physical control, the most recently engaged zone wins it. Turn on Zone Following in the toolbar and engaging any zone automatically releases the others, which keeps things predictable when you have a lot of them.
Smaller zones automatically sit on top of larger overlapping ones, so you can put a small zone inside a big one and the small one still gets the tap.
Transparent Zone
A Transparent Zone punches a genuine hole through a panel running as a local window. Not a dark rectangle, not an approximation — the window itself is cut away, so whatever is sitting behind it shows through and stays fully clickable.
The obvious use is a bezel overlay. Park a DCS MFD export, a GlassOut display, or any other window on your second monitor, lay a HangarControl panel with bezel buttons on top of it, and cut a Transparent Zone where the screen should be. You get the real display with your own working bezel around it.
Overlay mode switches on by itself: the moment a panel contains at least one Transparent Zone, its local window cuts the holes. Panels without one behave as a normal opaque window. The holes rescale with the window, so resizing keeps everything lined up.
This happens live. Drop a Transparent Zone onto a panel that is already open and the cutout appears straight away, and it follows the zone as you drag and resize it, which is the only practical way to line one up with a display behind it. Delete the last zone on the page and the window goes back to solid on the spot.
Template
Templates are full-page HTML documents that render in an embedded iframe, similar to gauges but designed for reference material rather than instruments. HangarControl ships with built-in templates like the CRAFT Clearance notepad (available in Blue, Green, and HangarControl themes). Templates are scrollable and fill the widget area. Add them through the right-click menu using Add Template....
5. Widget Editing
There are two ways to configure a widget, and they are the same editor either way. Click a widget once and its full editor appears in the properties pane down the right side of the designer, below the position and size sliders. Or double-click the widget to get that same editor in a floating dialog with Save, Clear, and Cancel buttons. Use whichever suits you; the pane is quicker for a lot of small edits, the dialog gives you more room.
Appearance changes apply live as you type. Action, state, and display value changes are committed when you move to another widget, change page or panel, or save. Changes are previewed live in the browser as you make them.
Target Zones are the exception — they are always configured in the properties pane rather than the dialog, because their options are entirely different from a button's.
Appearance
| Property | Description |
|---|---|
| Type | Widget type (Button, Gauge, Display, Label, Spacer, Image, Web View, Slider). Changing type reconfigures the available options. Target Zones and Transparent Zones are created from the canvas right-click menu rather than converted here. |
| Main Label | The widget's primary text, with its own color and font size. |
| H Align / V Align | Horizontal (left, center, right) and vertical (top, center, bottom) placement of the main label. |
| Main Label X / Y | Pixel offsets to nudge the main label in any direction. |
| Secondary Label | An additional label with its own color, font size, and X/Y offsets. Useful for a category name or an annotation alongside the main label. |
| Background | Hex color for the widget background. Use transparent for no background. |
| Border Color / Border Width | Border appearance. See Borders below. |
| Press Animation | Show a visual depression when the widget is touched. |
| Rotation | Rotate the widget by any angle from −180 to 180 degrees. This control lives in the IMAGE section but applies to the widget itself, so it works on any widget type. |
Labels & Text
Widgets can display several independently positioned text elements:
- Main Label — The primary text of the widget. Positioned by horizontal alignment (left, center, right) and vertical alignment (top, center, bottom).
- Secondary Label — A second label with its own color, font size, and offsets. Useful for category labels or annotations alongside the main label.
- Display Values — One or more live values driven by simulator variables, each with its own font, color, alignment, position, and optional caption (see Display Values).
Each text element supports pixel offsets (X and Y) for fine-tuning position. Set the offset values in the edit dialog to nudge text in any direction.
Icons
Widgets can display an icon from HangarControl's built-in icon library. Select an icon category and then pick the specific icon. Icons are rendered as SVG and scale cleanly to any size.
- Icon Category — Filter icons by category. Two categories behave differently from the rest: Multi-Position Switches and Magnetos & Ignition contain icons that draw more than one detent, and picking one of those sets up Position States for you automatically.
- Icon — The specific icon to display.
- Icon Color — Override color for the icon (hex). Defaults to the widget's text color.
- Icon Render Size (sharpness) — A slider from 8 to 512, defaulting to 36. This is the resolution the icon is rendered at, not the size it displays — raise it if an icon looks soft on a high DPI tablet.
- Switch ON Text and Switch OFF Text — The words drawn on a rocker icon, for panels whose switches read something other than ON and OFF, such as AVAIL or STBY. Longer words shrink automatically to fit the switch. Leave either box blank to keep the standard wording. Only rocker icons draw words on themselves, so these have no effect on any other icon.
Custom State Icons
For buttons that toggle between states (on/off), you can use custom imported images instead of the icon library. Enable Custom State Icons in the edit dialog, then browse for an ON image and an OFF image. When the widget's active state changes (based on a watch variable), the icon switches automatically.
Borders & Corners
- Border Color — Hex color or
transparent. Defaults totransparent, so a new widget has no visible border until you pick a color. - Border Width — Thickness in pixels (0 to 6). Set to 0 for no border. A border only draws when the width is above 0 and a color other than transparent is set.
- Press Animation — When enabled, the widget shows a subtle press effect on touch (scale down + border highlight).
6. Actions
Actions define what happens when a widget is pressed in the browser. Button and Display widgets support the full action system.
Press Types
Each widget supports up to five independent press types. Each press type can be assigned a different action:
| Press Type | Trigger |
|---|---|
| Short | Normal tap or click. This is the default. |
| Long | Press and hold beyond the long-press threshold. |
| Hold | Fires repeatedly while held. Configure the repeat interval in milliseconds. |
| Release | Fires when the button is released. |
| Double Tap | Two quick taps within the double-tap window (configurable, default 300ms). |
Use the tabs at the top of the action section in the edit dialog to switch between press types. Tabs with an action configured are shown in bold. The TIMING block at the bottom of the action section sets the thresholds: short press maximum, long press minimum, hold repeat interval, and the double tap window.
Action Modes
Each press type can do more than fire one command. The Action Mode dropdown sets how it behaves:
| Mode | Behavior |
|---|---|
| Single Action | Fires one command. This is the default and covers most buttons. |
| Sequence | Fires a list of commands in order on a single press, with a configurable delay before each step and an optional hold time. Add steps with Add Step, or insert a wait with Add Pause. Good for start-up flows and anything that needs several events in the right order. |
| Step Cycle | Cycles through a list of commands, firing the next one on each press. Ideal for a rotary selector driven from a single button. |
| Toggle (ON/OFF) | Alternates between an ON command and an OFF command. Configure each one separately with the Configure ON and Configure OFF buttons. |
| Toggle From Variable | Same ON and OFF pair, but the choice comes from the simulator rather than from a remembered position. Reads the State Monitor variable and sends the ON action when it is under the Threshold, the OFF action when it is at or over it. |
Action Types
The following action types are available for each press type:
| Action Type | Description |
|---|---|
| None | No action. The widget is purely visual. |
| SimConnect Event | Fire a SimConnect K: event (MSFS). Browse or search the full SimConnect event catalog. Optionally send a data value with the event. |
| Keyboard | Send a keyboard shortcut (e.g., Ctrl+Shift+F1). Useful for add-on aircraft that use keyboard bindings. |
| X-Plane Command | Send an X-Plane command (e.g., sim/flight_controls/flaps_down). |
| X-Plane DataRef | Write a specific value to an X-Plane DataRef. |
| DCS Command | Send a DCS command (device ID + command ID) with an optional value. Toggle between pulse (press and release) and hold modes. |
| Set Flag | Set a HangarControl flag to ON. |
| Clear Flag | Set a HangarControl flag to OFF. |
| Toggle Flag | Flip a HangarControl flag between ON and OFF. |
| Set HC Variable | Set a HangarControl variable to a specific value. |
| Increment HC Variable | Increase a HangarControl variable by a step amount, with optional min/max clamping. |
| Decrement HC Variable | Decrease a HangarControl variable by a step amount, with optional min/max clamping. |
| Page Navigation | Move between pages on this panel. See Page & Panel Navigation. |
| Next Panel / Previous Panel | Cycle forward or backward through the panels attached to this profile. |
| Go To Panel | Jump straight to a specific panel, picked by name from a dropdown. |
| vJoy Button | Press a virtual joystick button on a vJoy device. Choose the device and the button number. |
| vJoy Axis | Set a vJoy axis (X, Y, Z, RX, RY, RZ, and the sliders) to a specific value. Center is 16384. |
Guard Conditions
Any press type can be given a Guard Condition: a test that has to pass before the action is allowed to fire. Tick Enable Guard Condition and set a variable, an operator, and a value.
The variable can be an LVar, a SimVar, a Flag, an HC Variable, a DCS cockpit argument, or DCS telemetry, and there is a browse button to find it. Operators are !=, ==, >, <, >=, and <=.
Use it for anything that should not happen at the wrong moment — a gear lever that refuses to move while weight is on wheels, a start switch that only works once the battery is on, an autopilot mode button that ignores presses until the master is engaged.
Page & Panel Navigation
In addition to simulator actions, widgets can navigate between pages and panels.
Page Navigation offers three choices in its Navigate dropdown:
- Go to a specific page — Uses a 0-based page index, so the first page is 0 and a four page panel goes up to 3.
- Next page and Previous page — These wrap around, so they keep working when you add or remove pages. Prefer these unless you specifically need to land on one page.
Panel navigation moves between whole panels without changing the browser URL:
- Next Panel and Previous Panel — Cycle through all panels attached to this profile.
- Go To Panel — Jump directly to one specific panel, chosen by name from a dropdown rather than by position, so it keeps working when you reorder your panels.
Every browser and local window viewing a panel also has a floating control cluster with previous page and next page arrows, a fullscreen button, and a settings button. See Installing as an App.
Changing Pages From Hardware
Pages do not have to be changed from the screen. Any physical control HangarControl can bind — a button, a switch position, an encoder detent — can change pages too. Bind it as normal and set the Action Type to Touch Panel Page.
- Panel — Which panel to drive. Leave it on All Panels unless you run more than one at a time; that setting keeps working if you later rebuild the panel, where a specific panel chosen by name does not.
- Go To — Next Page, Previous Page, or a specific page number. Next and Previous wrap around.
This is what you want for a physical panel that has two roles. Build each role as its own page, bind the mode switch to Touch Panel Page, and the screen follows the switch with nothing to press.
7. State Monitoring
Watch Variables
Any Button or Display widget can monitor a simulator variable and change its appearance based on the value. Tick Enable Active State in the STATE MONITOR section to reveal the options:
- Watch Type — The variable source: LVar, SimVar, Flag, HC Variable, DCS Argument, or DCS Telemetry (LoGet).
- Variable — The variable name to monitor. Use the browse button to pick one from the catalog for the selected type.
- Units — Units for SimVars (e.g.
number,bool,degrees). - Threshold — The value at which the widget becomes "active." Default is 0.5. For flags and booleans, any value above this threshold is considered ON.
The same section also holds Selection Group and Armed Axis, covered below. A widget can use a watch variable, a selection group, or both.
Active States (Two State)
When a watch variable crosses the active threshold, the widget enters its "active" state. You can configure separate colors for the active state:
- Active Background Color — Replaces the normal background.
- Active Text Color — Replaces the normal text color.
- Active Icon Color — Replaces the normal icon color.
- Active Label — Replaces the label text when active.
If Custom State Icons are enabled, the widget switches between the ON and OFF images automatically.
Position States (More Than Two)
The Threshold and Active colors above describe a widget with exactly two states. Real cockpits are full of controls that have more — a magneto has five, a flap selector has three, an autopilot mode annunciator might have half a dozen. Position States handle those.
At the bottom of the STATE MONITOR section is a list of rules with a + Add Position State button. Each rule tests the watch variable and, if it matches, supplies the appearance for that position. Rules are checked top to bottom and the first match wins.
Rule Fields
- Match When Value — The comparison: Equals, Not Equals, Greater Than, Greater or Equal, Less Than, Less or Equal, or Between (inclusive).
- Value — The value to compare against.
- Upper Value — Only used by Between. The rule matches anywhere from Value to Upper Value, both ends included.
- Label — Text shown while this rule matches. Leave blank to keep the widget's own label. Each rule's label has its own font size, X and Y offsets, and a Bold label option.
- Background, Text Color, Icon Color — Appearance while this rule matches. Leave any of them blank to fall back to the widget's own color.
- Border Color — Only visible if the widget's Border Width is above 0, which is why the field says so.
- Highlight — Adds a glow border and an icon state dot. Seeded rules get this ticked by default.
- Custom Image — An optional image for this position, browsed from disk. Overrides the icon for that rule only. This works on any widget, including one with no icon of its own, so a button can be driven entirely by per position images. On a widget with no icon, the image is cleared whenever no rule matches.
Automatic Seeding From The Icon
You usually will not build these by hand. Several icons in the library know how many detents they have, and picking one seeds the rules for you:
| Icon | Positions | Detent Names |
|---|---|---|
| Magneto Key Switch (MAGNETOS, MAG 1, MAG 2, L MAG, R MAG) | 5 | OFF, R, L, BOTH, START |
| 3-Position Rocker — Horizontal and 3-Position Slide Switch | 3 | Left, Centre, Right |
| 3-Position Rotary Selector | 3 | Pos 1, Pos 2, Pos 3 |
| 3-Position Bat Toggle and 3-Position Rocker — Vertical | 3 | Up, Centre, Down |
Select one of these and three things happen at once: one rule is created per detent (Equals 0, Equals 1, and so on up), Enable Active State ticks itself, and the STATE MONITOR panel opens. Picking a switch is the intent, so making you hunt for the enable box first would only be in the way.
Each seeded rule is headed with the detent's real cockpit name where one exists, so position 4 on a magneto reads Position 4 (BOTH) rather than a bare number. Icons without known legends fall back to Position #4.
All you have to supply is the watch variable. Point it at the magneto SimVar and the switch turns to the right detent on its own.
Rotation & Movement
A widget can turn and slide from a variable, which is what makes a knob, a compass card, a trim wheel, or a moving pointer work with one image instead of a folder full of them.
Both settings live in the ROTATION block of the STATE MONITOR section, under the watch variable that drives them.
Rotate Continuously From The Variable
Use this when the movement is evenly spaced. Tick Rotate continuously from the variable and fill in four fields:
- Degrees per unit — How far the image turns for each whole step of the variable. A knob with detents 15 degrees apart reading 1, 2, 3 gets 15 here.
- Variable value at the start angle and Start angle — Together these say where zero is. If the variable reads 3 when the knob is pointing straight up, put 3 and 0 in these two fields.
- Minimum angle and Maximum angle — Hard stops. The image will not turn past these however far the variable runs, which keeps a knob inside the travel the real one has.
Rotate To Match Position
Use this when the detents are not evenly spaced, which covers most real selector knobs. Tick Rotate to match position and give each position rule its own Rotation. The first rule that matches supplies the angle, exactly as it already supplies colours and labels, so you type the real angles rather than relying on even maths.
If both settings are on, the rules win wherever one matches and the continuous mapping covers everything else.
Slew X and Slew Y
Position rules can also shift a widget sideways and up or down, for controls that slide rather than turn. Set Slew X and Slew Y on each rule in pixels. Movement is applied before rotation, so a widget that does both still turns about its own centre.
Selection Groups
Give several buttons the same Selection Group name and they start behaving like a set of radio buttons. Tap one and it arms, highlighted using its active color mapping, and the others in the group clear automatically. Only one member of a group is ever armed.
On its own this is a clean way to build a mode selector. Paired with a slider it becomes something better. Set a Slider to Drive the armed target and put the group name in its Follow Selection Group field, and that one slider now drives whichever button in the group is armed.
For that to work in continuous mode, each button in the group needs an Armed Axis set: the axis target the slider should drive while that button is the armed one. Click Set... next to Armed Axis and pick a SimConnect event, an LVar, a DCS axis, or an X-Plane DataRef.
The result is one physical-feeling control that retargets on demand. Four buttons labelled COM1, COM2, NAV1, NAV2 above a single slider, and the slider tunes whichever one you last tapped.
Display Values
Widgets can show live simulator values as text. Tick Enable Display Values in the DISPLAY VALUES section, then click + Add Display Value for each one you want. A single widget can carry as many as you need, each completely independent, which is what lets one widget become a small readout panel rather than just a number.
Each display value has:
- Type — Variable source (SimVar, LVar, Flag, HC Variable).
- Variable and Units — What to read and in what units.
- Format — Format string for the number (e.g.
F0for no decimals,F2for two decimal places,N0for thousands separators). - Label — An optional caption shown with the value, with its own font size, color, and X/Y offsets. Give the offset a negative Y to sit the caption above the value.
- Font Size, Color, and Font Family — Per-value styling, independent of the widget's own text settings.
- Offset X / Offset Y and Align — Position each value anywhere within the widget and set its text alignment.
8. Gauges
Gauge widgets display interactive HTML instruments rendered in an embedded iframe. They are driven by simulator variables and update in real time with smooth animation.
Gauge Library
HangarControl ships with a library of built-in gauges organized by category:
- Basic — Airspeed Indicator, Altimeter, Vertical Speed, Heading, RPM, Fuel Quantity, Manifold Pressure, and EGT. Simple circular and bar gauges, quick to drop in and rebind to whatever aircraft you are flying.
- Cessna 172 — A full six-pack. Tachometer with Hobbs meter and green arc, airspeed indicator with colored arcs and a TAS ring, three-pointer altimeter with Kollsman window and baro knob, HSI with heading bug and course pointer, vertical speed indicator, and turn coordinator with inclinometer ball. Plus the C172 Electrical Panel: a working keyed magneto switch with spring loaded START, split ALT/BATT master, avionics BUS 1 and BUS 2, fuel pump, all five lights, pitot heat, and nine push/pull circuit breakers. Switch the Preset to Unbound to bind it to any aircraft.
- GA Avionics — Working avionics bezels. GA Autopilot Panel (GFC-style, with AP, HDG, NAV, APR, REV, ALT, VS, altitude select, and baro), GA Transponder, GA Transponder (Advanced) with a mode knob, full squawk entry, IDENT, VFR, reply lamp, power-up self test, and FUNC pages for flight timer and stopwatch, plus G1000 PFD/MFD, GNS 530 GPS/NAV/COM, and GTN 750 Touchscreen GPS/NAV/COM.
The library is stored in %AppData%\HangarControl\gauge-library\. Each gauge is a folder containing a gauge.html file and a manifest.json file.
Built-in gauges are refreshed from the application on every launch, so an update that improves a shipping gauge reaches you automatically. Gauges you import yourself are never touched by this and stay exactly as you left them.
Importing Gauges
You can import custom gauge HTML files to expand the library:
- Add a Gauge widget to your panel (right-click canvas, Add Gauge).
- Double-click the gauge to open the edit dialog.
- In the GAUGE section, click Import Gauge HTML....
- Select your HTML file. HangarControl auto-detects setter functions and creates the manifest.
- The imported gauge appears in the gauge dropdown and is permanently available in the library.
Input Bindings
When you select a gauge, the editor shows the gauge's input bindings. Each input maps a JavaScript setter function in the gauge to something in the simulator:
- Type — SimVar, H: Event, B: Event, LVar, HC Variable, Flag, DCS Argument, DCS Telemetry (LoGet), or Text.
- Variable — The variable or event name (e.g.
INDICATED ALTITUDE,AIRSPEED INDICATED). A browse button opens the right catalog for the type you picked. - Units — Units for the variable (e.g.
feet,knots,degrees). Hidden for event and text types, which do not use them. - SimConnect Event — Shown for SimVar inputs only. This is what makes a gauge interactive.
That last field is worth understanding. A gauge input normally just reads a value and moves a needle. Add a SimConnect event to it and tapping or turning that part of the gauge writes back to the sim. That is how the C172 altimeter's baro knob actually sets your altimeter, and how every softkey on the G1000 bezel does something. The field is editable on every SimVar input, so you can point any gauge control at whatever event your particular aircraft wants rather than being stuck with the default.
Choose the Text type to pin a fixed string into a gauge with no interpolation, which is handy for labelling a bezel or showing a static identifier.
Built-in gauges come with sensible default bindings. Custom imported gauges start with empty bindings that you fill in based on what the gauge expects.
9. Images & Templates
Adding Images
Right-click the canvas and select Add Image... to open a file picker. Select any image file (PNG, JPG, GIF, BMP, WebP, SVG). HangarControl imports the image into its asset folder and creates an Image widget sized to the image's aspect ratio.
Images are served from %AppData%\HangarControl\touchpanel-assets\. Once imported, the image is available for any panel or widget.
Image Options
In the edit dialog for an Image widget:
| Property | Description |
|---|---|
| Fit Mode | Contain scales to fit inside the widget without cropping. Cover scales to fill, cropping if needed. Stretch distorts the image to fill exactly. Fill fills the widget area. |
| Crop (Top/Right/Bottom/Left) | Inset percentages to crop the image (0 to 50 per side). |
| Rotation | Rotate from −180 to 180 degrees. Applies to any widget type, not just images. |
Built-In Templates
Templates are full HTML documents that render in an iframe, perfect for reference materials, notepads, and checklists. To add a template:
- Right-click the canvas and select Add Template....
- The Template Picker dialog opens, showing all available templates with descriptions.
- Select a template and click Select.
- The template is placed on the canvas at approximately 90% of the canvas size.
Templates are scrollable in the browser, so content can be larger than the widget area. They auto-scale to fit the widget dimensions.
Shipping Templates
| Template | Description |
|---|---|
| CRAFT Clearance (Blue) | IFR clearance notepad in blue aviation theme. |
| CRAFT Clearance (Green) | IFR clearance notepad in green theme. |
| CRAFT Clearance (HC) | IFR clearance notepad in HangarControl orange theme. |
The CRAFT acronym covers the five elements of an IFR clearance: Clearance limit, Route, Altitude, Frequency, and Transponder code. Each template provides large writing areas for each element plus an additional notes section.
10. Panels & Groups
Managing Panels
The panel list on the left side of the designer shows all panels in the global library. Panels are global objects that can be shared across profiles.
- Add — Create a new blank panel.
- Remove — Remove the panel from the current profile without deleting it from the library.
- Attach — Attach the selected panel to the current profile. If a group header is selected instead, the whole group is attached.
- Detach — Detach the selected panel or group from the current profile.
- Copy — Duplicate the selected panel with all pages, layers, and widgets.
- Delete — Permanently delete the selected panel from the global library.
- Export — Save the selected panel as a
.hcpanelfile to share. Its images and any custom gauges it uses are packed inside, so it opens complete on another PC. - Import — Add a panel from a
.hcpanelfile. It always arrives as a new panel, so it never overwrites one you already have, even an earlier import of the same file.
Attached panels are marked in the list so you can see at a glance which ones belong to the profile you are editing.
Panel Groups
Groups let you organize panels into logical sets. For example, you might have a "Boeing 737" group with an overhead panel, a pedestal panel, and a radio panel.
- New Group — Create a named group.
- To Group — Add the selected panel to a group.
- Del Group — Delete a group (panels inside are not deleted, just ungrouped).
You can drag and drop panels between groups in the panel list.
Attaching to Profiles
Groups can be attached to or detached from profiles. When a profile is activated, all panels in its attached groups start automatically (if enabled).
- Attach — Links the selected group to the current profile. Panels in the group will start when this profile is active.
- Detach — Unlinks the group from the profile. Panels will no longer auto-start for this profile.
This system lets you reuse the same panel layouts across multiple aircraft profiles while keeping them organized.
11. Networking & Access
Localhost Access
By default, every panel is accessible at http://localhost:{port} from the same computer. Localhost access never requires administrator privileges and works immediately.
LAN / Wi-Fi Access
To access panels from other devices on your network (tablets, phones, other PCs), the server needs to bind to all network interfaces instead of just localhost.
This is automatic. When a panel starts, HangarControl tries to bind to all interfaces. If that fails for want of administrator rights, it creates a URL reservation and a Windows Firewall rule for that port, prompting once for elevation. Approve the prompt and the rule is permanent, so you should not be asked again for that port. If elevation is declined or the retry still fails, the panel falls back to localhost only and keeps working on the PC itself.
The connection bar in the designer tells you which you got. When LAN access is live it shows both the localhost address and the Wi-Fi / LAN address ready to type into your tablet. When it is not, it shows the localhost address alone.
Finding Your PC's IP Address
On your PC, open a command prompt and type ipconfig. Look for your Wi-Fi or Ethernet adapter's IPv4 address (e.g., 192.168.1.100). On your tablet or phone, open the browser and navigate to http://192.168.1.100:19860 (substituting your IP and port).
Installing as an App
Every panel is an installable web app. On a tablet or phone, open the panel in the browser and use Add to Home Screen (or Install on desktop Chrome and Edge). The panel installs as its own app, named after the panel, with its own icon.
Launched that way it opens fullscreen with no browser chrome at all — no address bar, no tabs, nothing but your panel. The orientation is locked to match your canvas, so a wide panel opens landscape and a tall one opens portrait. If you run several panels, each installs as its own separate app, so a G1000 and a GTN 750 sit side by side on your home screen as two distinct icons.
You can also just tap the fullscreen button in the floating controls if you would rather not install anything.
On-Screen Controls
Every panel viewed in a browser has a small floating cluster of buttons with previous page, next page, fullscreen, and a settings gear. The settings menu holds four per-device toggles:
- Show Header Bar — Panel title, page name with position, and connection status.
- Show Footer Bar — A slim footer strip.
- Show Page/Settings Buttons — Hides the floating cluster itself once you are finished setting up.
- Show Connection Status — The small connection indicator.
These are saved on each device, so your tablet can run clean and fullscreen while the browser window on your desk keeps its header and status visible.
Refocus Process
If you are using a touchscreen monitor mounted near your flight sim rig (not a separate device), you probably want the simulator to stay in the foreground after each touch. The Refocus dropdown in the toolbar lets you select a running application. After each touch on any control, whether a button, gauge, slider, target zone or page button, HangarControl pushes focus back to that application. To turn it off, set the dropdown back to (Disabled).
This is only relevant for local touchscreen setups. If you are using a separate tablet or phone, the simulator's focus is never affected because touches happen on a different device entirely.
12. Local Window
A local window opens a touch panel as its own native window directly on the PC running HangarControl, with no web browser involved. It is a clean, borderless window you can place on any monitor, move, resize, and maximize like any other application. This is the ideal way to run a panel on a dedicated touchscreen or a spare monitor on your sim rig.
Opening a Local Window
There are three ways to open one:
- Open Window button in the designer toolbar. Opens the panel on the screen selected in the Screen dropdown.
- Right-click the panel where it is attached to a profile (in the main window's attached devices list) and choose Open Local Window Now.
- Enable Auto Window so it opens automatically whenever the profile is selected (see below).
Auto Open Toggles
Each panel has two independent auto-open toggles: Auto Browser and Auto Window. Whatever you enable opens automatically the moment that panel's profile is selected. You can enable either, both, or neither.
Both toggles appear in two places, and they always stay in sync because they are the same per-panel setting:
- In the designer toolbar, as the Auto Browser and Auto Window checkboxes.
- In the right-click menu on the panel where it is attached to a profile, as Auto Open Browser and Auto Open Local Window.
Choosing a Screen
The Screen dropdown in the toolbar picks which monitor the local window opens on. The list shows every connected display with its resolution, and the primary monitor is marked. The window opens centered on the chosen screen at the panel's canvas size, ready for you to move or resize.
Move, Resize & Maximize
The window has no permanent title bar, so it stays clean and edge to edge. A slim dark strip drops down only when you move the cursor to the very top edge of the window. That strip carries the panel name, a maximize / restore button, and a close button.
- Move — drag the strip while it is showing. Windows snapping (Aero Snap) works too.
- Resize — drag any edge or corner, just like a normal window.
- Maximize / Restore — click the button on the strip, or double-click the strip. Maximize fills the screen's work area and is clamped so it never covers the taskbar.
- Close — the button on the strip.
Remembered Position
Each panel remembers its own local window placement. When you move, resize, or maximize the window and then close it, HangarControl saves the exact position, size, and maximized state, and reopens the window right where you left it next time.
If the monitor the window last lived on is no longer connected, it falls back to centered on the screen selected in the dropdown instead of opening out of view. Picking a new monitor in the Screen dropdown clears the remembered position so the window opens fresh on the new screen; the next time you move it, that new spot is what sticks.
Transparent Overlay Mode
A local window can become a true overlay. Put one or more Transparent Zone widgets on the panel and the window opens in overlay mode, cutting a real hole through itself wherever a zone sits. Whatever is behind shows through and stays clickable.
Nothing to switch on: the window checks the panel for Transparent Zones as it opens and decides for itself. Remove the last zone and it goes back to a normal opaque window. The holes track the window as you resize it, so the alignment holds.
This is how you build a bezel around a display you do not control. Park a DCS MFD export or a GlassOut viewer on a monitor, open a HangarControl panel over it with your bezel artwork and buttons, and cut the middle out.
WebView2 Runtime
The native local window uses the Microsoft Edge WebView2 runtime, which is already present on the vast majority of Windows 10 and 11 systems. On the rare machine that does not have it, the window will tell you it could not open and point you to install the runtime, rather than failing silently. The browser method never needs it.
13. GlassOut Integration
GlassOut renders glass-cockpit displays from your simulator. HangarControl can place a GlassOut display inside or behind your touch panel so you can build interactive controls directly over real glass — bezel buttons around a PFD, softkeys under an MFD, and so on.
Embedding GlassOut
Add a Web View widget and click the GlassOut button next to the URL field. Enter your GlassOut engine address (port 8787 by default) and click Connect, and you get a list of the panels the engine is currently serving. Pick one and the URL is built for you.
The picker also offers a fit mode: Stretch fills the widget exactly and is the usual choice, Contain letterboxes to preserve the aspect ratio, and Native renders at 1:1 pixels. When you pick a panel, the widget is automatically reshaped to that panel's native aspect so a stretched fit fills it with no letterboxing.
You can also type a URL directly if you prefer (for example http://192.168.0.245:8787/panel/PFD_Captain). The GlassOut display renders live inside that widget, and you can size and position it like any other widget on the page.
For a tablet or phone over WiFi, there is no need to change the address. Leave it as 127.0.0.1 and HangarControl points it at your PC automatically when the panel is opened from another device.
Designer Backdrop
Aligning buttons to a live display is hard if you cannot see it while you design. To solve this, HangarControl can capture a single still frame of a GlassOut panel and paint it as a true-to-size backdrop on the designer canvas. With the real glass shown behind your work area, you can position every overlay precisely where it needs to sit.
When you add a Web View widget and pick a GlassOut panel, the designer grabs that snapshot automatically. No live stream is kept open while you design — it is a frozen reference image purely for alignment.
Overlay Touch Zones
Once the glass is in place, lay your interactive widgets on top of it. Buttons work as usual. For knobs, dials, and drag controls, the Slider / Touch Zone widget set to the Hidden display style is perfect: it gives you an invisible, draggable hit area that sits directly over a portion of the glass and fires your chosen actions, with nothing visible to clutter the display.
14. Building Custom Gauges
This chapter takes you from zero to a fully functioning, animated cockpit gauge that works inside HangarControl's Touch Panel system. No prior coding experience is required.
Setup
What You Need
- A text editor — Notepad++ is free and has syntax highlighting that makes code easier to read. Any text editor works.
- A web browser — Chrome, Edge, or Firefox. You already have one.
- HangarControl — For importing and testing.
How HangarControl Gauges Work
A HangarControl gauge is a single HTML file. One file. Inside that file you draw your gauge using SVG (a way to draw shapes with code) and you expose a JavaScript function that HangarControl calls to update the gauge.
- You create an HTML file with your gauge drawing and a function like
setAltitude(value). - You import the file into HangarControl.
- HangarControl detects your function automatically.
- You tell HangarControl which simulator variable to read (like "INDICATED ALTITUDE").
- HangarControl reads that variable from the simulator and calls your function with the value.
- Your function moves the needle.
HangarControl handles all the simulator communication. You just draw the gauge and write the function that moves the needle.
The Blank Canvas
Create a new file and save it as my-altimeter.html. Start with this structure:
<style>
.gauge { text-align: center; }
.gauge svg { max-width: 460px; display: block; margin: 0 auto; }
</style>
<div class="gauge">
<svg id="mySvg" viewBox="0 0 460 460" width="100%"></svg>
</div>
<script>
(function(){
// All our code will go here
})();
</script>
Open it in a browser. You will see a blank page. That is correct. The <svg> element is your drawing canvas, 460 units wide and tall. Point (230, 230) is the exact center.
<!DOCTYPE html>, <html>, <head>, or <body> tags. HangarControl wraps your gauge in its own HTML shell automatically. Just start with your <style>, <div>, and <script>.
Drawing the Gauge Face
Inside the <script> section, add a helper function and draw the face:
var svg = document.getElementById('mySvg');
var ns = 'http://www.w3.org/2000/svg';
var cx = 230, cy = 230; // Center of our gauge
// Helper function to create SVG elements
function mk(tag, attributes) {
var el = document.createElementNS(ns, tag);
for (var key in attributes) {
el.setAttribute(key, attributes[key]);
}
return el;
}
// Draw the gauge face â a dark circle
svg.appendChild(mk('circle', {
cx: cx, cy: cy, r: 185,
fill: '#0a0a0a', stroke: '#333333',
'stroke-width': 2
}));
Save and refresh. You should see a dark circle. cx and cy are the center coordinates. r: 185 is the radius. fill: '#0a0a0a' is the fill color in hex (almost black).
</style>not</style}— The closing tag must use an angle bracket>, not a curly brace}. A curly brace causes the browser to swallow your entire page as CSS.viewBoxnotviewbox— SVG attributes are case-sensitive. Lowercaseviewboxis silently ignored and your gauge will not render.- Count your closing brackets — The
svg.appendChild(mk('circle', { ... }));line needs three closers:}for the object,)formk(), and)forappendChild(). A missing paren kills the entire script with no visible error on the page. - Press F12 and click Console — Red errors there will tell you exactly what line is broken. This is your best friend when debugging gauges.
Tick Marks & Numbers
Add a polar coordinate helper and a loop for tick marks:
// Convert angle + radius to x,y coordinates
function pol(angleDegrees, radius) {
var radians = (angleDegrees - 90) * Math.PI / 180;
return [
cx + Math.cos(radians) * radius,
cy + Math.sin(radians) * radius
];
}
// Draw 50 tick marks
for (var i = 0; i < 50; i++) {
var angle = i * 7.2; // 360 / 50 = 7.2 per tick
var isMajor = (i % 5 === 0);
var outerR = 180;
var innerR = isMajor ? 155 : 168;
var sw = isMajor ? 2.5 : 1.2;
var outer = pol(angle, outerR);
var inner = pol(angle, innerR);
svg.appendChild(mk('line', {
x1: outer[0], y1: outer[1],
x2: inner[0], y2: inner[1],
stroke: '#f0f0f0', 'stroke-width': sw,
'stroke-linecap': 'round'
}));
}
Every 5th tick is a major tick (longer and thicker). The pol() function converts a compass angle and distance from center into pixel coordinates.
Add numbers around the dial:
for (var n = 0; n <= 9; n++) {
var angle = n * 36; // 360 / 10 = 36 per number
var pos = pol(angle, 138);
var t = mk('text', {
x: pos[0], y: pos[1],
fill: '#f0f0f0', 'font-size': '28',
'font-family': 'Arial, sans-serif',
'font-weight': '700',
'text-anchor': 'middle',
'dominant-baseline': 'central'
});
t.textContent = n;
svg.appendChild(t);
}
Creating a Needle
Create a needle using a group element so you can rotate it as one unit:
var needle = mk('g', { id: 'myNeedle' });
// Shadow for depth
needle.appendChild(mk('line', {
x1: cx+1, y1: cy+20, x2: cx+1, y2: cy-160,
stroke: '#000', 'stroke-width': 4,
opacity: '0.3', 'stroke-linecap': 'round'
}));
// The needle body
needle.appendChild(mk('rect', {
x: cx-2, y: cy-155, width: 4, height: 165,
rx: 1, fill: '#ffffff'
}));
// Needle tip triangle
needle.appendChild(mk('polygon', {
points: (cx-2.5)+','+(cy-153)+' '+
cx+','+(cy-172)+' '+
(cx+2.5)+','+(cy-153),
fill: '#ffffff'
}));
svg.appendChild(needle);
The Setter Function
This is the critical part. This is what HangarControl calls to update your gauge:
window.setAltitude = function(feet) {
feet = Math.max(0, Math.min(10000, feet));
var degrees = ((feet % 1000) / 1000) * 360;
needle.setAttribute('transform',
'rotate(' + degrees + ',' + cx + ',' + cy + ')');
};
window. Always write window.setMyFunction = function(value) { ... }. This is how HangarControl discovers and calls your setter. If you write function setMyFunction(value) without window., HangarControl will not detect it.
You can test it immediately. Open your browser's developer console (press F12, click "Console") and type:
setAltitude(500)
The needle should jump to the 5 position.
How the Math Works
feet % 1000 gives just the hundreds portion. At 4,500 feet this gives 500. Dividing by 1000 converts to a fraction (0.5). Multiplying by 360 converts to degrees (180 degrees).
Smooth Animation
Real instruments sweep smoothly. Replace the setter with an animated version:
var currentAngle = 0, targetAngle = 0, animating = null;
function animate() {
var diff = targetAngle - currentAngle;
if (diff > 180) diff -= 360;
if (diff < -180) diff += 360;
if (Math.abs(diff) < 0.1) {
currentAngle = targetAngle;
needle.setAttribute('transform',
'rotate('+currentAngle+','+cx+','+cy+')');
animating = null; return;
}
currentAngle += diff * 0.12;
if (currentAngle < 0) currentAngle += 360;
if (currentAngle >= 360) currentAngle -= 360;
needle.setAttribute('transform',
'rotate('+currentAngle+','+cx+','+cy+')');
animating = requestAnimationFrame(animate);
}
window.setAltitude = function(feet) {
feet = Math.max(0, Math.min(10000, feet));
targetAngle = ((feet % 1000) / 1000) * 360;
if (!animating) animating =
requestAnimationFrame(animate);
};
The 0.12 multiplier controls speed. Smaller = slower and smoother. Larger = faster response. requestAnimationFrame runs the animation at 60fps for silky smooth movement.
Testing in HangarControl
Make sure your my-altimeter.html file is saved.
Add a Gauge widget to your panel (right-click canvas, Add Gauge).
Double-click the gauge widget. In the GAUGE section, click Import Gauge HTML... and select your file.
You will see INPUT BINDINGS with one entry: Altitude (setAltitude). Set Type to SimVar, Variable to INDICATED ALTITUDE, Units to feet.
Click Save and open the panel in a browser. Your gauge needle should track your aircraft's altitude in real time.
Multiple Needles
A real altimeter has three needles: a long thin one for hundreds, a medium one for thousands, and a short fat one for ten-thousands. Create three separate needle groups and update the setter to calculate three angles:
window.setAltitude = function(feet) {
feet = Math.max(0, Math.min(20000, feet));
// Hundreds: full revolution per 1,000ft
tar100 = ((feet % 1000) / 1000) * 360;
// Thousands: full revolution per 10,000ft
tar1k = ((feet % 10000) / 10000) * 360;
// Ten-thousands: proportional
tar10k = (feet / 100000) * 360;
if (!animating)
animating = requestAnimationFrame(animate);
};
Multiple Inputs (Barometric Window)
A gauge can have multiple setter functions, each mapped to a different variable. Add a second setter for barometric pressure:
window.setBaroPressure = function(inHg) {
if (inHg > 100) inHg = inHg * 0.02953;
inHg = Math.max(28.00, Math.min(31.00, inHg));
var display = document.getElementById('baroDisplay');
if (display) display.textContent = inHg.toFixed(2);
};
When you import this gauge, HangarControl will show two input bindings: one for altitude and one for baro pressure. Bind the baro to SimVar KOHLSMAN SETTING HG in inHg units.
Polish & Finishing
Once your gauge works, you can add visual polish. These are purely cosmetic and do not affect functionality:
- Bezel — A metallic ring around the gauge. Use radial gradients transitioning from lighter at the top-left to darker at the bottom-right to simulate a light source.
- Case — A square mounting plate behind the gauge, with corner screws.
- Glass overlay — A subtle semi-transparent gradient across the face to simulate glass reflection. Use
rgbacolors with very low opacity. - Inner shadows — Radial gradients that darken the edges of the gauge face for depth.
Drawing Order
The order you draw elements matters. Later elements appear on top. The correct order from bottom to top is:
- Square case and corner screws
- Depth recess
- Bezel ring and bezel screws
- Gauge face (black circle)
- Inner shadow
- Color arcs (if any)
- Tick marks and numbers
- Labels (ALTITUDE, KNOTS, etc.)
- Digital readouts
- Needles (shortest first, longest last)
- Center cap
- Glass overlay and reflections
Quick Reference: Gauge Rules
| Rule | Details |
|---|---|
| One HTML file | Everything goes in a single .html file. |
Setter functions use window. | Always write window.setMyFunction = function(value) { ... }. |
| Function names are auto-detected | HangarControl scans for window.setXxx = function patterns. |
| No external files | Do not reference external CSS, JS, or image files. Everything must be inline. |
| SVG for drawing | Use SVG elements: circle, rect, line, polygon, path, text. |
| Remove debug controls | Sliders, range inputs, and debug divs are automatically stripped on import. |
| Test in a browser first | Use the console (F12) to call your setter functions before importing. |
| Values come from the sim | You write the function that accepts a number and moves the needle. HangarControl provides the numbers. |
Common SimConnect Variables for Gauges
| Variable | Units | Description |
|---|---|---|
INDICATED ALTITUDE | feet | Current altitude |
AIRSPEED INDICATED | knots | Indicated airspeed |
HEADING INDICATOR | degrees | Heading from gyro |
VERTICAL SPEED | feet per minute | Rate of climb/descent |
KOHLSMAN SETTING HG | inHg | Barometric pressure |
GENERAL ENG RPM:1 | rpm | Engine 1 RPM |
NAV OBS:1 | degrees | NAV1 OBS setting |
AUTOPILOT HEADING LOCK DIR | degrees | AP heading bug |
FUEL TOTAL QUANTITY | gallons | Total fuel |
GENERAL ENG EXHAUST GAS TEMPERATURE:1 | fahrenheit | EGT engine 1 |
RECIP ENG MANIFOLD PRESSURE:1 | inHg | Manifold pressure engine 1 |
Common Hex Colors for Gauges
| Color | Hex | Use |
|---|---|---|
| Gauge face (near black) | #0a0a0a | Main background |
| Tick marks / text | #f0f0f0 | Light markings |
| Needle (white) | #ffffff | Primary needle |
| Needle (red/orange) | #ff3300 | Warning needle |
| Green arc | #00aa44 | Normal operating range |
| Yellow arc | #ccaa00 | Caution range |
| Red line | #ff0000 | Never-exceed limit |
| White arc | #ffffff | Flap operating range (airspeed) |
| Bezel silver | #808080 to #c0c0c0 | Metallic bezel ring |
| Glass highlight | rgba(255,255,255,0.04) | Subtle glass sheen |
This guide was created for HangarControl by Overkill Simulations.