betomoedano / magnet-eyes
git clone https://github.com/betomoedano/magnet-eyes.git
SwiftUI magnetometer experiment with animated eyes and a live magnetic-field grid.
—
stars, 24h
+29
stars, 7 days · #1,366
+29
stars, 30 days · #9,089
29
★ total · +29% this week
1
forks · 0 open issues
Star history starts 2026-10-20; the chart appears after the second daily snapshot.
LanguageSwift
License—
Created2026-10-16 (4d ago)
Last push4d ago
Watchers1
OwnerUser
Links
README excerpt
# Magnet Eyes A small SwiftUI iPhone experiment that turns magnetic-field changes into animated eyes. Switch to **Field** to see the same response as a vector on a grid. *Screenshots show the simulator’s explicitly labeled Demo mode.* Built with SwiftUI and Apple’s Core Motion. No external dependencies, API keys, or network services. `MagnetEyesCore` is a local Swift package. ## Run it You need Xcode with an iOS 17 or later SDK. A physical iPhone with a magnetometer is required for live readings. 1. Open `MagnetEyes.xcodeproj` and select the **MagnetEyes** scheme. 2. For a physical device, select your own development team under **Signing & Capabilities** and choose your iPhone. Use a unique bundle identifier if your signing setup requires one. 3. Run the app. It starts in **Live sensor** mode. Allow Motion access if iOS requests it. 4. Place the phone on a nonmagnetic support, remove the magnet and magnetic phone accessories, and tap **Recenter**. Keep it still for about one second while the baseline is captured. 5. Bring a small, weak fridge magnet nearby and move it slowly, keeping the same face and orientation toward the phone. Avoid powerful magnets and magnetic phone accessories. The simulator has no magnetometer. It shows **NO SENSOR** until you explicitly select **Try demo** or **Field controls → Demo**. You can also use the `--demo` launch argument for simulator previews. Remove that argument before testing live readings. Demo is never silently substituted for the sensor. ## Controls | Control | Behavior | | --- | --- | | **Eyes / Field** | Switch between the character and the measured field-change plot. | | **Recenter** | Capture a fixed ambient-field baseline with the phone still and magnet removed. | | **Field range** | Set the grid to ±50, ±200, or ±1000 µT. An out-of-range marker is clipped and labeled; numeric values remain unchanged. | | **Field axes** | Select X/Y, X/Z, or Y/Z for the eyes and grid. | | **Sensitivity / inversion** | Tune the eyes’ response. The grid retains measured signs and units. | | **Show field readings** | Show raw X/Y/Z readings and the magnitude of the field change on the Eyes screen. | | **Camera mode** | Hide controls for filming the selected view. It does not record video or access the camera. Demo disclosure stays visible. | Updates stop while the app is inactive. Live mode requires a fresh baseline after resuming. Missing hardware, stale readings, and sensor errors produce a visible state instead of invented data. ## How it works `CMMotionManager` delivers `CMMagnetometerData`: a three-axis magnetic field in microteslas (µT). 1. Request samples at approximately 60 Hz; actual delivery depends on the device. 2. Smooth the field with a time-based low-pass filter (0.10-second time constant). 3. Subtract a stationary baseline: `ΔB = filtered B − baseline B`. 4. Map two selected components to the pupils, with a radial 1.5 µT deadzone and adjustable sensitivity. 5. Smooth the gaze (0.065-second time constant