Build a Smiling Bag Loading Animation with SVG and CSS

This step‑by‑step guide shows how to combine SVG graphics and CSS animations to create a loading indicator shaped like a smiling shopping bag, covering viewport setup, path drawing, styling, keyframe animation, and motion along paths.

Aotu Lab
Aotu Lab
Aotu Lab
Build a Smiling Bag Loading Animation with SVG and CSS

Introduction

CSS3 animations are powerful, but some effects require SVG. This tutorial demonstrates how to create a loading animation that looks like a smiling shopping bag by using CSS for rotation and SVG for the mouth shape.

Step 1 – Declare the SVG viewport

Define a 100 × 100 pixel SVG area:

<svg width="100" height="100"></svg>

The default coordinate system places the origin at the top‑left, with x increasing to the right and y increasing downward.

Step 2 – Draw the bag body

Use a <path> element to draw the main part of the bag:

<path d="M 20 40 L 80 40 L 80 90 A 10 10 90 0 1 70 100 L 30 100 A 10 10 90 0 1 20 90" style="fill:#e9e8ee;"/>

The fill attribute sets the interior color. The path commands are: M 20 40 – move pen to (20,40) L 80 40 – draw a line to (80,40) A 10 10 90 0 1 70 100 – draw an elliptical arc

Next, draw the top half‑arc of the bag:

<path d="M 35 40 A 15 15 180 1 1 65 40" style="fill:none;stroke:#e9e8ee;stroke-width:5;"/>

Step 3 – Draw the eyes

<circle cx="40" cy="60" r="2.5" style="fill:#fff;"/>
<circle cx="60" cy="60" r="2.5" style="fill:#fff;"/>

Two small white circles represent the eyes.

Step 4 – Draw the mouth

<circle cx="50" cy="70" r="15" style="fill:none;stroke:#fff;stroke-width:5;stroke-linecap:round;transform:rotate(280deg);transform-origin:50% 50%;stroke-dashoffset:-23;stroke-dasharray:42,95;"/>

The mouth is a circular arc created by stroking only a segment of a circle and rotating it into place.

Step 5 – Animate the mouth

@keyframes mouth {
  0%   {transform:rotate(-80deg);stroke-dasharray:60,95;stroke-dashoffset:0;}
  40%  {transform:rotate(280deg);stroke-dasharray:60,95;stroke-dashoffset:0;}
  70%,100% {transform:rotate(280deg);stroke-dashoffset:-23;stroke-dasharray:42,95;}
}

The animation first rotates the arc, then shortens it to form a smile, holding the final state for the last 30 % of each loop.

Step 6 – Animate the eyes

Define a motion path for the right eye:

<path id="eyeright" d="M 40 60 A 15 15 180 0 1 60 60" style="fill:none;stroke-width:0;"/>

Attach <animateMotion> to a circle representing the eye:

<circle cx="" cy="" r="2.5" style="fill:#fff;">
  <animateMotion dur="0.8s" repeatCount="indefinite" keyPoints="0;0;1;1" keyTimes="0;0.3;0.9;1" calcMode="linear">
    <mpath xlink:href="#eyeleft"/>
  </animateMotion>
</circle>

The same approach is used for the left eye, synchronizing the eye motion with the mouth animation.

Step 7 – Combine all parts

Both the mouth and eye animations share four key time points; the eye animation starts slightly earlier to ensure a smooth transition.

References

MDN SVG documentation

《SVG精髓》 (People's Posts and Telecommunications Press)

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendWeb DesignLoading Indicator
Aotu Lab
Written by

Aotu Lab

Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.