muscle_mapper 0.0.4 copy "muscle_mapper: ^0.0.4" to clipboard
muscle_mapper: ^0.0.4 copied to clipboard

A pure Dart/Flutter UI package providing a 2D human anatomy model with multi-select muscle highlighting and a BYOA (Bring Your Own Asset) architecture.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:muscle_mapper/muscle_mapper.dart';

void main() {
  runApp(const MuscleMapperExampleApp());
}

class MuscleMapperExampleApp extends StatelessWidget {
  const MuscleMapperExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Muscle Mapper Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MuscleMapperExamplePage(),
    );
  }
}

class MuscleMapperExamplePage extends StatefulWidget {
  const MuscleMapperExamplePage({super.key});

  @override
  State<MuscleMapperExamplePage> createState() =>
      _MuscleMapperExamplePageState();
}

enum InteractionMode { subMuscle, group }

class _MuscleMapperExamplePageState extends State<MuscleMapperExamplePage> {
  final Set<Muscle> _selectedMuscles = {};
  InteractionMode _mode = InteractionMode.group;
  AnatomyGender _gender = AnatomyGender.male;
  AnatomyView _view = AnatomyView.front;

  void _onMuscleTapped(Muscle tappedMuscle) {
    setState(() {
      if (_mode == InteractionMode.subMuscle) {
        if (_selectedMuscles.contains(tappedMuscle)) {
          _selectedMuscles.remove(tappedMuscle);
        } else {
          _selectedMuscles.add(tappedMuscle);
        }
      } else {
        final groupMuscles = tappedMuscle.group.subMuscles;
        if (_selectedMuscles.containsAll(groupMuscles)) {
          _selectedMuscles.removeAll(groupMuscles);
        } else {
          _selectedMuscles.addAll(groupMuscles);
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Muscle Mapper Example'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Wrap(
              spacing: 16.0,
              runSpacing: 16.0,
              alignment: WrapAlignment.center,
              children: [
                SegmentedButton<AnatomyGender>(
                  segments: const [
                    ButtonSegment(
                        value: AnatomyGender.male, label: Text('Male')),
                    ButtonSegment(
                        value: AnatomyGender.female, label: Text('Female')),
                  ],
                  selected: {_gender},
                  onSelectionChanged: (selection) =>
                      setState(() => _gender = selection.first),
                ),
                SegmentedButton<AnatomyView>(
                  segments: const [
                    ButtonSegment(
                        value: AnatomyView.front, label: Text('Front')),
                    ButtonSegment(value: AnatomyView.back, label: Text('Back')),
                  ],
                  selected: {_view},
                  onSelectionChanged: (selection) =>
                      setState(() => _view = selection.first),
                ),
                SegmentedButton<InteractionMode>(
                  segments: const [
                    ButtonSegment(
                      value: InteractionMode.group,
                      label: Text('Group Mode'),
                    ),
                    ButtonSegment(
                      value: InteractionMode.subMuscle,
                      label: Text('Sub-Muscle Mode'),
                    ),
                  ],
                  selected: {_mode},
                  onSelectionChanged: (newSelection) {
                    setState(() {
                      _mode = newSelection.first;
                      _selectedMuscles.clear();
                    });
                  },
                ),
              ],
            ),
          ),
          Expanded(
            child: Center(
              child: SizedBox(
                width: 300,
                height: 500,
                child: MuscleMapper(
                  gender: _gender,
                  view: _view,
                  assetProvider: const DefaultAnatomyProvider(),
                  activeMuscles: _selectedMuscles,
                  onMuscleTapped: _onMuscleTapped,
                  highlightColor: Colors.redAccent,
                  baseColor: Colors.grey.shade300,
                ),
              ),
            ),
          ),
          SizedBox(
            height: 120, // Fixes height to exactly 2 rows of Chips
            width: double.infinity,
            child: SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              padding: const EdgeInsets.all(16.0),
              child: Wrap(
                direction: Axis
                    .vertical, // Forces chips to fill columns vertically first
                spacing: 8.0,
                runSpacing: 8.0,
                children: _selectedMuscles.map((m) {
                  return Chip(
                    label: Text(m.name),
                    onDeleted: () {
                      setState(() => _selectedMuscles.remove(m));
                    },
                  );
                }).toList(),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
8
likes
0
points
368
downloads

Publisher

verified publishersuryamouly.in

Weekly Downloads

A pure Dart/Flutter UI package providing a 2D human anatomy model with multi-select muscle highlighting and a BYOA (Bring Your Own Asset) architecture.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_svg, path_drawing, xml

More

Packages that depend on muscle_mapper