Back to Dictionary
Status & Confirmation
●●○Customize
Context dependent

Checkmark Draw Animation

An SVG checkmark that progressively draws itself from left to right inside a circle, confirming a successful action.

Use

Payment success screens

Avoid

Routine toggles (too dramatic)

Safer Alternative

No safer default listed.

Risk Level

Low risk

Live Demo

What It Is

An SVG checkmark that progressively draws itself from left to right inside a circle, confirming a successful action.

When to Use

  • Payment success screens
  • Form submission successes
  • Task completion

When NOT to Use

  • Routine toggles (too dramatic)
  • Indeterminate states

Configuration Tips

  • 01Use SVG dasharray and dashoffset manipulation to draw the path
  • 02Animate the circle scaling up, then draw the checkmark after a 100ms delay

You've Seen It In

Stripe CheckoutApple PayLottieAnimations

AI Implementation Prompts

Move from a fast scaffold to production details, then tune timing and edge states.

Add a success checkmark that looks like it is being drawn with a pen.

Reference Implementation

The same implementation approach used by the live preview, kept compact enough to inspect and adapt.

'use client';
import { motion } from 'framer-motion';
import { useState, useEffect } from 'react';

export function CheckmarkDrawAnimationDemo({ isPlaying = false }: { isPlaying?: boolean }) {
    const [isSuccess, setIsSuccess] = useState(false);

    useEffect(() => {
        if (!isPlaying) {
            setIsSuccess(false);
            return;
        }
        const interval = setInterval(() => {
            setIsSuccess((prev) => !prev);
        }, 1500);
        return () => clearInterval(interval);
    }, [isPlaying]);

    return (
        <div className="flex h-64 w-full items-center justify-center rounded-2xl bg-white p-6 shadow-sm ring-1 ring-stone-200">
            <div className="flex h-24 w-24 items-center justify-center rounded-full bg-stone-50">

                {"text-stone-400 italic">/* Expanding Success Bubble */}
                <motion.div
                    animate={isSuccess ? { scale: 1, opacity: 1 } : { scale: 0.5, opacity: 0 }}
                    transition={{ type: 'spring', stiffness: 300, damping: 20 }}
                    className="flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500 shadow-sm"
                >
                    {"text-stone-400 italic">/* Drawing SVG Path */}
                    <svg className="h-8 w-8 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
                        <motion.path
                            initial={{ pathLength: 0 }}
                            animate={isSuccess ? { pathLength: 1 } : { pathLength: 0 }}
                            transition={{ delay: 0.2, type: 'tween', ease: 'easeOut', duration: 0.5 }}
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            d="M5 13l4 4L19 7"
                        />
                    </svg>
                </motion.div>

            </div>
        </div>
    );
}