MuscleMap SDK

repository·main·Indexed 42 days ago

https://github.com/melihcolpan/musclemap

A native SwiftUI SDK for rendering interactive human body muscle maps. It supports SVG-based rendering of 36 muscle groups, heatmaps with customizable color scales, and complex gestures like drag-to-select and pinch-to-zoom. Compatible with iOS 17+ and macOS 14+, it includes UIKit wrappers via MuscleMapView and HeatmapLegendUIView, VoiceOver accessibility support, and localization for 11 languages.

Tokens
8.5K
Snippets
32
Records
43
Agent score
54%

What's inside MuscleMap

  1. Overview of MuscleMap features

    main

    MuscleMap is a native SwiftUI SDK for rendering interactive human body muscle maps.

    Key Capabilities:

    • Rendering: SVG-based rendering via SwiftUI Canvas supporting 36 muscle groups (22 base + 14 sub-groups) with male/female and front/back models.
    • Interactions: Tap-to-select, multi-select, long press, drag-to-select (painting), and pinch-to-zoom/pan.
    • Visualizations: Heatmaps with customizable color scales, gradient fills (linear/radial), and pulse/glow animations for selected muscles.
    • UI Components: Tooltips, undo/redo selection history, and 4 preset styles (default, minimal, neon, medical).
    • Compatibility: Works with SwiftUI and provides UIKit wrappers (MuscleMapView, HeatmapLegendUIView).
    • Requirements: iOS 17+ or macOS 14+; zero external dependencies.
  2. Understand Muscle Sub-Groups

    main

    Sub-groups allow for finer control over specific muscle regions. They inherit the parent muscle's highlight if no specific sub-group highlight is set and take priority in hit testing.

    Key Properties

    • Hierarchy: You can query relationships using Muscle.chest.subGroups, Muscle.upperChest.parentGroup, or Muscle.upperChest.isSubGroup.
    • Always-Visible Sub-groups: Certain sub-groups like .ankles, .adductors, and .neck are rendered by default. Tapping these areas returns their parent muscle (e.g., tapping .ankles returns .feet).

    Usage Example Highlighting a parent and a sub-group with different intensities allows for layered visual effects.

    // Highlight parent and sub-group with different intensities
    BodyView(gender: .male, side: .front)
        .highlight(.chest, color: .red, opacity: 0.4)       // parent (dimmer)
        .highlight(.upperChest, color: .red, opacity: 0.9)   // sub-group (brighter)
        .highlight(.quadriceps, color: .blue, opacity: 0.4)
        .highlight(.innerQuad, color: .blue, opacity: 0.9)
  3. Visualizing Heatmaps

    main

    MuscleMap supports heatmap visualizations to represent muscle intensity or data density. This is managed through a combination of color scales and configurations.

    Key components:

    • HeatmapConfiguration: Settings for the heatmap display.
    • HeatmapColorScale: Defines the color mapping for intensities.
    • MuscleIntensity: Represents the data value for a muscle.
    • ColorInterpolation: Determines how colors transition.
    • GradientDirection: Controls the direction of color gradients.
    • HeatmapLegendView: A view used to display the heatmap scale/legend.
  4. Accessibility support in MuscleMap

    main

    MuscleMap provides built-in VoiceOver support. Each muscle region is automatically exposed as an accessibility element featuring:

    • Localized muscle names as the accessibility label.
    • Selection state (e.g., "Selected" or "Not selected").
    • Tap and long press hints.
    • Anatomical top-to-bottom traversal order.

    Cosmetic elements like the head are excluded from the accessibility tree to reduce noise.

  5. Highlighting Muscles

    main

    You can visually emphasize specific muscles using the .highlight() modifier on a BodyView. This allows for single-color fills or more complex styling.

    Key components:

    • Muscle: Represents a specific muscle (e.g., .chest, .biceps).
    • MuscleSide: Indicates which side of the body the muscle belongs to.
    • MuscleHighlight: Defines the highlight state.
    • MuscleFill: Defines how the muscle is filled.
  6. Visualize muscle intensity with heatmaps

    main

    MuscleMap allows you to render muscle intensity data using color-coded heatmaps on a BodyView. You can map intensity values (0.0–1.0) to specific color scales, apply interpolation for smooth transitions, and use thresholds to filter out low-intensity data.

    BodyView()
        .heatmap([
            MuscleIntensity(muscle: .chest, intensity: 0.9),
            MuscleIntensity(muscle: .biceps, intensity: 0.5),
            MuscleIntensity(muscle: .abs, intensity: 0.3),
        ], colorScale: .thermal)
  7. Integrate MuscleMap with UIKit using MuscleMapView

    main

    For UIKit-based projects, use MuscleMapView as a drop-in UIView wrapper. You can initialize it with a specific gender and side, apply highlights to specific muscles, and handle tap detection via the onMuscleSelected closure.

    To use it, add it to your view hierarchy and set up constraints as you would with any other UIView.

    import MuscleMap
    
    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let muscleMap = MuscleMapView(gender: .male, side: .front)
            muscleMap.highlight(.chest, color: .systemRed)
            muscleMap.highlight(.biceps, color: .systemOrange, opacity: 0.8)
            muscleMap.onMuscleSelected = { muscle, side in
                print("\(muscle.displayName) tapped")
            }
    
            view.addSubview(muscleMap)
            muscleMap.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                muscleMap.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                muscleMap.centerYAnchor.constraint(equalTo: view.centerYAnchor),
                muscleMap.widthAnchor.constraint(equalToConstant: 300),
                muscleMap.heightAnchor.constraint(equalToConstant: 500)
            ])
        }
    }
  8. Integrate MuscleMap in UIKit projects

    main

    Although MuscleMap is built with SwiftUI, you can use it in UIKit-based projects via the MuscleMapView class, which acts as a UIView wrapper. All configuration is managed through mutable properties and convenience methods on the view instance.

    import MuscleMap
    
    class ViewController: UIViewController {
        private let muscleMap = MuscleMapView(gender: .male, side: .front)
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            muscleMap.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(muscleMap)
    
            NSLayoutConstraint.activate([
                muscleMap.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                muscleMap.centerYAnchor.constraint(equalTo: view.centerYAnchor),
                muscleMap.widthAnchor.constraint(equalToConstant: 200),
                muscleMap.heightAnchor.constraint(equalToConstant: 400),
            ])
        }
    }