magic-loading

Text-to-magic-circle loading indicator

Deterministic Generation

Same text always produces the same magic circle. Different text = different circle.

Interactive

Try changing text and progress to see the effect in real time.

Indeterminate Mode

Omit the progress attribute for a looping pulse animation. Useful when total progress is unknown.

CSS Custom Property Override

By default, colors are derived from the text hash. Override with CSS custom properties for brand-consistent colors.

magic-loading {
  --ml-color-primary: #ff6b6b;
  --ml-color-secondary: #ffd93d;
  --ml-color-glow: #ff6b6b;
}

CSS Properties

Property Default Description
--ml-color-primary Auto (hash) Ring strokes, glyphs, center symbol
--ml-color-secondary Auto (hash) Inner polygon strokes
--ml-color-glow Auto (hash) Glow filter color

Setup

Install

npm install @yeonseong/magic-loading

Web Component

Import once, then use the <magic-loading> tag anywhere.

<script type="module">
  import '@yeonseong/magic-loading';
</script>

<!-- Determinate: shows progress 0~1 -->
<magic-loading text="Uploading..." progress="0.5" size="120"></magic-loading>

<!-- Indeterminate: omit progress for pulsating loop -->
<magic-loading text="Loading..." size="120"></magic-loading>

Programmatic API

For dynamic control — update progress, change text, trigger completion.

import { create } from '@yeonseong/magic-loading';

const loader = create(document.getElementById('container'), {
  text: 'Loading...',
  size: 160,
  progress: 0,
});

loader.setProgress(0.5);       // update progress
loader.setText('Almost done'); // regenerate circle
await loader.complete();       // burst animation
loader.destroy();              // remove from DOM

CDN (no build step)

<script src="https://unpkg.com/@yeonseong/magic-loading/dist/index.global.js"></script>
<script>
  const loader = MagicLoading.create(
    document.getElementById('loader'),
    { text: 'Hello', size: 120 }
  );
</script>

Framework Examples

Works with any framework — just import and use.

// React
import '@yeonseong/magic-loading';
function Loader({ text, progress }) {
  return <magic-loading text={text} progress={progress} size={120} />;
}

// Vue
<template>
  <magic-loading :text="text" :progress="progress" size="120" />
</template>
<script setup>
import '@yeonseong/magic-loading';
</script>

Attributes

Attribute Type Default Description
text string - Text to hash into a unique magic circle (required)
progress number | null null 0~1 for determinate. Omit for indeterminate pulsating mode
size number 120 Width and height in pixels