muscle_map
Interactive Flutter muscle maps for workout and fitness apps. Display male or female body diagrams, select muscle groups, and visualize workout intensity.
Fork of muscle_selector by EmilCes. This package extends the original with intensity mapping, additional muscle groups, and bug fixes.
Features
- Interactive SVG-based human body diagrams (full body, front only, back only)
- Male and female body variants sharing the same muscle ids, so they can be swapped at runtime
MusclePickerMap— tap muscles to select/deselect them; get a callback with the selected setMuscleIntensityMap— display muscles colored by workout intensity (light / medium / hard)- Custom muscle colors, intensity palettes, outline strokes, loading states, and crossfades
- Bundled SVG assets and cached parsing; no network requests are needed to display a map
Installation
Add to your pubspec.yaml:
dependencies:
muscle_map: ^1.3.0
Then run:
flutter pub get
Requires Dart 3.2.6 or later, below Dart 4, and a compatible Flutter SDK. The body SVGs are bundled with the package; no asset entries are needed in your app.
Usage
MusclePickerMap
Lets users tap muscles to select them. Returns a Set<Muscle> on every change.
import 'package:flutter/material.dart';
import 'package:muscle_map/muscle_map.dart';
MusclePickerMap(
map: Maps.BODY, // see Body Maps below
onChanged: (muscles) {
print(muscles); // Set<Muscle>
},
strokeColor: Colors.black,
selectedColor: Colors.blue,
actAsToggle: true, // tap again to deselect
initialSelectedGroups: ['chest', 'biceps'],
)
MuscleIntensityMap
Displays muscles colored by intensity level. Pass an initialSelectedGroups map of group name → MuscleIntensity.
import 'package:flutter/material.dart';
import 'package:muscle_map/muscle_map.dart';
MuscleIntensityMap(
map: Maps.FEMALE_BODY,
initialSelectedGroups: {
'chest': MuscleIntensity.light,
'biceps': MuscleIntensity.hard,
'triceps': MuscleIntensity.hard,
'shoulders': MuscleIntensity.medium,
},
onChanged: (muscles) {},
strokeColor: Colors.black,
)
Body Maps
| View | Male | Female |
|---|---|---|
| Front and back together | Maps.BODY |
Maps.FEMALE_BODY |
| Front only | Maps.FRONT_BODY |
Maps.FEMALE_FRONT_BODY |
| Back only | Maps.BACK_BODY |
Maps.FEMALE_BACK_BODY |
Corresponding male and female views expose the same muscle IDs and group keys. Both widgets accept all six maps:
MusclePickerMap(map: Maps.FEMALE_FRONT_BODY, onChanged: (muscles) {})
Helpers for building a switcher:
Maps.male // [BODY, FRONT_BODY, BACK_BODY]
Maps.female // [FEMALE_BODY, FEMALE_FRONT_BODY, FEMALE_BACK_BODY]
Maps.isFemale(map) // true for any female map
Maps.familyOf(map) // the full / front / back trio of that body
Maps.toggleGender(Maps.BACK_BODY) // -> Maps.FEMALE_BACK_BODY
Changing map reloads the diagram and reinitializes its selection from
initialSelectedGroups or initialSelectedMuscles. To retain selected groups
when switching views or bodies, keep those group keys in your app's state and
pass them through initialSelectedGroups for the new map. A front-only or
back-only view displays only the regions present in that view.
The diagrams are stylized exercise-selection maps. Female variants include revised body proportions, hair, hip/glute contours, and hands while preserving the muscle-region contract.
Customization
| Option | Widget | Purpose |
|---|---|---|
selectedColor, muscleColors |
MusclePickerMap |
Set a default selection color or colors by muscle ID, such as chest1 |
intensityColorBuilder |
MuscleIntensityMap |
Map MuscleIntensity values to your own colors |
strokeColor, strokeWidth, strokeCap, strokeJoin |
Both | Style diagram outlines |
showSkeleton, loadingBuilder |
Both | Disable or replace the loading placeholder |
skeletonColor and skeletonAnimationDuration |
Both | Customize the built-in loading placeholder |
enableCrossfade, crossfadeDuration |
Both | Control transitions when the map content changes |
For example, color individual regions in a picker:
MusclePickerMap(
map: Maps.FEMALE_FRONT_BODY,
initialSelectedGroups: ['chest'],
muscleColors: {
'chest1': Colors.teal,
'chest2': Colors.teal,
},
strokeColor: Colors.black,
onChanged: (muscles) {},
)
Muscle Groups
The following group keys can be used with initialSelectedGroups:
chest, shoulders, obliques, abs, abductor, biceps, calves, forearm, glutes, harmstrings, lats, upper_back, quads, trapezius, triceps, adductors, lower_back, neck
Use the legacy spelling harmstrings when targeting the hamstrings group.
Group keys such as chest select multiple regions; individual IDs such as
chest1 and chest2 identify paths in the SVGs.
Example
The example app demonstrates selection, intensity colors, styling options, and the Male / Female and Full / Front / Back controls. From a checkout of this repository, run:
cd example
flutter pub get
flutter run
Development
Run the package checks from the repository root:
flutter test
flutter pub publish --dry-run
The map tests check bundled assets, matching muscle IDs, parseable paths, compatible geometry bounds, and the body-switching helpers. See tool/README.md for regenerating the female SVGs.
Credits
Forked from muscle_selector by EmilCes.
License
See LICENSE.