Arc Timeline
svelte-animations/arc-timelineFreeBlock
A curved timeline that rotates through milestone steps with clickable markers, icons, and configurable spacing.
Install it
npx shadcn@latest add https://sv-animations.vercel.app/r/arc-timeline.jsonSource
1<script lang="ts">2 import type { Snippet } from "svelte";3 import { cn } from "$UTILS$";4 import type {5 ArcTimelineItem,6 ArcTimelineProps,7 ArcTimelineRenderable,8 ArcTimelineStep,9 } from "./types";1011 interface TimelineStepMeta {12 line: ArcTimelineItem;13 step: ArcTimelineStep;14 lineIndex: number;15 stepIndex: number;16 angle: number;17 isFirstStep: boolean;18 isLastStep: boolean;19 }2021 let {22 ref = $bindable(null),23 class: className,24 data,25 arcConfig = {},26 defaultActiveStep = {},27 ...restProps28 }: ArcTimelineProps = $props();2930 let circleWidth = $derived(arcConfig.circleWidth ?? 5000);31 let angleBetweenMinorSteps = $derived(arcConfig.angleBetweenMinorSteps ?? 0.35);32 let lineCountFillBetweenSteps = $derived(arcConfig.lineCountFillBetweenSteps ?? 10);33 let boundaryPlaceholderLinesCount = $derived(arcConfig.boundaryPlaceholderLinesCount ?? 50);3435 function getInitialCircleRotation() {36 const defaultActiveTime = defaultActiveStep.time ?? data[0]?.time;37 const defaultActiveStepIndex = defaultActiveStep.stepIndex ?? 0;3839 let count = 0;4041 for (const timelineItem of data) {42 if (timelineItem.time === defaultActiveTime) {43 count += defaultActiveStepIndex;44 break;45 }4647 count += timelineItem.steps.length;48 }4950 return (51 -count * angleBetweenMinorSteps * (lineCountFillBetweenSteps + 1) -52 angleBetweenMinorSteps * boundaryPlaceholderLinesCount53 );54 }5556 let circleContainerRotateDeg = $state(getInitialCircleRotation());5758 let timelineSteps = $derived.by((): TimelineStepMeta[] => {59 const steps: TimelineStepMeta[] = [];60 let stepsBeforeCurrentLine = 0;6162 data.forEach((line, lineIndex) => {63 line.steps.forEach((step, stepIndex) => {64 const angle =65 angleBetweenMinorSteps *66 (lineCountFillBetweenSteps + 1) *67 (stepsBeforeCurrentLine + stepIndex) +68 angleBetweenMinorSteps * boundaryPlaceholderLinesCount;6970 steps.push({71 line,72 step,73 lineIndex,74 stepIndex,75 angle,76 isFirstStep: lineIndex === 0 && stepIndex === 0,77 isLastStep:78 lineIndex === data.length - 1 && stepIndex === line.steps.length - 1,79 });80 });8182 stepsBeforeCurrentLine += line.steps.length;83 });8485 return steps;86 });8788 function getPlaceholderAngles(isFirstStep: boolean, isLastStep: boolean, angle: number) {89 const count =90 isLastStep || isFirstStep ? boundaryPlaceholderLinesCount : lineCountFillBetweenSteps;9192 return Array.from({ length: count }, (_, index) =>93 isFirstStep94// … truncated
Files it writes
More from Svelte Animations
All 66 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Beamanimated-beam | Svelte Animations | Blocks | Free | 1 dep · 6 files | |
| Animated Circular Progress Baranimated-circular-progress-bar | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Animated Gradient Textanimated-gradient-text | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Animated Grid Patternanimated-grid-pattern | Svelte Animations | Blocks | Free | 1 dep · 2 files | |
| Animated Listanimated-list | Svelte Animations | Blocks | Free | 1 dep · 2 files | |
| Animated Shiny Textanimated-shiny-text | Svelte Animations | Blocks | Free | no deps | |
| Animated Theme Toggleranimated-theme-toggler | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Aurora Textaurora-text | Svelte Animations | Blocks | Free | no deps · 2 files |
