line-drawingLine drawing
线条绘制English definition
Animating SVG stroke dash values reveals a path progressively along its length.
Chinese translation
SVG 路径像被一支隐形画笔描摹一样自行绘制出来。
line-drawingDraw icons, paths, or explanatory connectors with stroke offset animation.
Animating SVG stroke dash values reveals a path progressively along its length.
Implement Line drawing: Draw icons, paths, or explanatory connectors with stroke offset animation. Use Demo duration 1000ms, Delay 0ms, Easing calm. Trigger it once when state changes and keep it replayable. Use semantic HTML, scope CSS to .motion-demo--line-drawing. Provide equivalent low-motion behavior for prefers-reduced-motion and .force-reduced-motion.
<div class="motion-demo motion-demo--line-drawing" data-motion="line-drawing" aria-label="Line drawing demo">
<svg viewBox="0 0 240 120" role="img" aria-label="Line drawing"><path class="motion-path" d="M20 92 C54 16 104 18 126 67 S192 112 220 30"></path></svg>
</div>.motion-demo.motion-demo--line-drawing {
box-sizing: border-box;
position: relative;
display: grid;
place-items: center;
width: min(100%, 34rem);
min-height: 15rem;
padding: 2rem;
overflow: hidden;
color: #18181b;
background: #fafafa;
border: 1px solid #e4e4e7;
border-radius: 16px;
isolation: isolate;
}
.motion-demo.motion-demo--line-drawing *, .motion-demo.motion-demo--line-drawing *::before, .motion-demo.motion-demo--line-drawing *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--line-drawing .motion-surface {
position: relative;
display: grid;
gap: 0.65rem;
width: min(100%, 18rem);
padding: 1.25rem;
background: #ffffff;
border: 1px solid #e4e4e7;
border-radius: 16px;
box-shadow: none;
}
.motion-demo.motion-demo--line-drawing .motion-surface strong { font-weight: 500; }
.motion-demo.motion-demo--line-drawing .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--line-drawing .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--line-drawing .motion-button {
position: relative;
min-height: 2.75rem;
padding: 0.75rem 1.1rem;
color: white;
font: inherit;
font-weight: 700;
background: #18181b;
border: 0;
border-radius: 999px;
cursor: pointer;
}
.motion-demo.motion-demo--line-drawing .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--line-drawing .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--line-drawing .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--line-drawing .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--line-drawing button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--line-drawing .motion-replay-button,
.motion-demo.motion-demo--line-drawing .motion-undo-button,
.motion-demo.motion-demo--line-drawing .motion-dismiss-button,
.motion-demo.motion-demo--line-drawing .motion-pause-button {
min-height: 2.75rem;
padding: 0.65rem 0.9rem;
color: #18181b;
font: 650 0.78rem/1 ui-sans-serif, system-ui, sans-serif;
background: #ffffff;
border: 1px solid #d4d4d8;
border-radius: 8px;
cursor: pointer;
}
.motion-demo.motion-demo--line-drawing .motion-replay-button:focus-visible,
.motion-demo.motion-demo--line-drawing .motion-undo-button:focus-visible,
.motion-demo.motion-demo--line-drawing .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--line-drawing .motion-pause-button:focus-visible,
.motion-demo.motion-demo--line-drawing [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--line-drawing [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--line-drawing .motion-status {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.motion-demo.motion-demo--line-drawing .motion-ripple-ink {
position: absolute;
width: 12px;
height: 12px;
pointer-events: none;
background: rgb(255 255 255 / 72%);
border-radius: 50%;
transform: translate(-50%, -50%) scale(0.95);
opacity: 0;
}
.motion-demo.motion-demo--line-drawing .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--line-drawing .motion-state { position: absolute; inset: 0; display: grid; place-items: center; padding: 1rem; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 16px; }
.motion-demo.motion-demo--line-drawing .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--line-drawing .motion-scroll-track > span { color: #71717a; font: 600 0.72rem/1.2 ui-monospace, monospace; letter-spacing: 0.08em; text-transform: uppercase; }
.motion-demo.motion-demo--line-drawing .motion-orbit-item { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; color: white; background: #2563eb; border-radius: 50%; }
.motion-demo.motion-demo--line-drawing .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--line-drawing svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--line-drawing .motion-path { fill: none; stroke: #2563eb; stroke-width: 5; stroke-linecap: round; stroke-dasharray: 260; stroke-dashoffset: 260; animation: motion-line-drawing 1000ms cubic-bezier(0.33, 1, 0.68, 1) 0ms both; }
@keyframes motion-line-drawing { to { stroke-dashoffset: 0; } }
@keyframes motion-line-drawing-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--line-drawing {
animation: motion-line-drawing-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--line-drawing *,
.force-reduced-motion .motion-demo.motion-demo--line-drawing *::before,
.force-reduced-motion .motion-demo.motion-demo--line-drawing *::after {
animation: none !important;
animation-delay: 0ms !important;
animation-iteration-count: 1 !important;
transition-property: opacity, color, background-color, border-color !important;
transition-duration: 160ms !important;
transition-delay: 0ms !important;
scroll-behavior: auto !important;
}
.force-reduced-motion .motion-demo.motion-demo--line-drawing .motion-button,
.force-reduced-motion .motion-demo.motion-demo--line-drawing [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--line-drawing [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--line-drawing [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--line-drawing .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--line-drawing .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--line-drawing .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--line-drawing {
animation: motion-line-drawing-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--line-drawing *, .motion-demo.motion-demo--line-drawing *::before, .motion-demo.motion-demo--line-drawing *::after {
animation: none !important;
animation-delay: 0ms !important;
animation-iteration-count: 1 !important;
transition-property: opacity, color, background-color, border-color !important;
transition-duration: 160ms !important;
transition-delay: 0ms !important;
scroll-behavior: auto !important;
}
.motion-demo.motion-demo--line-drawing .motion-button,
.motion-demo.motion-demo--line-drawing [data-reorder-item],
.motion-demo.motion-demo--line-drawing [data-swipe-target],
.motion-demo.motion-demo--line-drawing [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--line-drawing .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--line-drawing .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--line-drawing .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}line-drawingAnimating SVG stroke dash values reveals a path progressively along its length.
SVG 路径像被一支隐形画笔描摹一样自行绘制出来。
Show the complete path immediately or with one very short fade.
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 500ms–3000ms | 1000ms | Uses a longer demo duration so the full change stays observable; immediate production UI feedback should stay under 300ms. |
delay | 0ms–600ms | 0ms | Controls the wait before motion begins. |
ease | Soft / Snap / Calm / Linear | Calm | Controls how velocity changes over time. |