Showcase

A hardened core for production motion. Flutter-native morphing that keeps state local, geometry explicit and springs physical — from clipboard confirmation to file-tree disclosure. Six everyday interactions where a morph clarifies intent without adding chrome.

WHY THIS PATH

Rotation is solved in closed form. If a pair is congruent under a similarity transform it rotates; otherwise it morphs in the aligned frame. No manual rotation groups.

WHAT IT WEIGHS

6.5 kB gzipped core, zero runtime dependencies, one shared Ticker for every icon on screen. Planning any pair costs <1 ms on a mid-range device.

THE TRADEOFF

Stroke is first-class; filled shapes reuse the same polar solver. Corners stay sharp at rest, and masks stay small to avoid an extra save-layer per frame.

Copy to clipboard

The most repeated swap: Copy settles into Check.

flutter pub add morphicons_flutter
tap card or icon → check

Password visibility

Eye to EyeOff on the input's trailing button.

Input
tap card or eye → eye-off

Theme toggle

Sun to Moon in one slot — no double SVG.

Toggle
tap card or icon → moon

Player controls

Play and pause, plus mute on the same cluster.

Audio
ambient-01.wav3:42
tap card → play/pause · tap speaker → mute

Inline validation

Trailing icon tracks the field: Check when valid, X when not.

Form
tap card to cycle · type to validate → check/x

File tree

Folders morph open; the disclosure chevron stays CSS.

Tree
lib
tap card or folder → open/close

Dart usage

Copy the smallest useful example.

core_patterns.dart
import 'package:flutter/material.dart';
import 'package:morphicons_lucide/morphicons_lucide.dart';
import 'package:morphicons_flutter/morphicons_flutter.dart';
class CopyButton extends StatefulWidget {
  const CopyButton({super.key});
  @override
  State<CopyButton> createState() => _CopyButtonState();
}
class _CopyButtonState extends State<CopyButton> {
  var copied = false;
  @override
  Widget build(BuildContext context) => IconButton(
    onPressed: () => setState(() => copied = true),
    icon: MorphIcon(icon: copied ? MorphIconsLucide.check : MorphIconsLucide.copy),
    tooltip: copied ? 'Copied' : 'Copy',
  );
}