Infinity Loop Loader インフィニティループローダー
Luminous glow stroke racing along an infinite SVG bezier curve. SVGの無限大パス上を周回するネオングロー光線のアニメーション演出。
ライブデモ Live Demo
読み込み中... Loading...
概要・用途・特徴Overview, Usage & Features
何ができるかWhat it does
An SVG-based loader featuring a smooth glowing beam continuously tracing an infinity symbol path.
無限大記号(∞ / レムニスケート)のベジェ曲線パスに沿って光の筋が連続して走り抜けるSVGローダーです。
どこで使うかWhere to use
Useful for background synchronization, data backups, perpetual polling, and modern web application loaders.
データ同期、バックグラウンド処理、ポーリング待機、モダンなWebアプリ全般のローディング画面に適しています。
特徴Key features
SVG stroke-dashoffset animation, drop-shadow glow filter, responsive SVG scaling, accessibility attributes, reduced-motion safe.
SVG stroke-dashoffsetアニメーション、ドロップシャドウによるグロー光彩、レスポンシブ拡大縮小、role="status"対応、prefers-reduced-motion考慮。
調整可能パラメータ Adjustable Parameters
| Parameter | Default | Description |
|---|---|---|
width | 84px | Width of the infinity loader container |
speed | 2.0s | Duration of one full cycle around the loop |
color | #38bdf8 | Luminous glow beam color |
実装コード Implementation Code
<div class="s018-loader" role="status" aria-label="Loading">
<span class="s018-sr-only">Loading</span>
<svg class="s018-svg" viewBox="0 0 100 50" aria-hidden="true">
<path class="s018-track" d="M25,25 C10,25 10,40 25,40 C40,40 60,10 75,10 C90,10 90,25 75,25 C60,25 40,40 25,40 C10,40 10,25 25,25 C40,25 60,40 75,40 C90,40 90,25 75,25 C60,25 40,10 25,10 C10,10 10,25 25,25 Z" />
<path class="s018-beam" d="M25,25 C10,25 10,40 25,40 C40,40 60,10 75,10 C90,10 90,25 75,25 C60,25 40,40 25,40 C10,40 10,25 25,25 C40,25 60,40 75,40 C90,40 90,25 75,25 C60,25 40,10 25,10 C10,10 10,25 25,25 Z" />
</svg>
</div>
.s018-loader {
--s018-width: 84px;
--s018-height: 48px;
--s018-speed: 2s;
--s018-track-color: rgba(148, 163, 184, 0.18);
--s018-glow-color: #38bdf8;
--s018-stroke-width: 4px;
position: relative;
width: var(--s018-width);
height: var(--s018-height);
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.s018-sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.s018-svg {
width: 100%;
height: 100%;
overflow: visible;
}
.s018-track {
fill: none;
stroke: var(--s018-track-color);
stroke-width: var(--s018-stroke-width);
stroke-linecap: round;
}
.s018-beam {
fill: none;
stroke: var(--s018-glow-color);
stroke-width: var(--s018-stroke-width);
stroke-linecap: round;
stroke-dasharray: 40 180;
stroke-dashoffset: 220;
filter: drop-shadow(0 0 6px var(--s018-glow-color));
animation: s018-trace var(--s018-speed) linear infinite;
}
@keyframes s018-trace {
to {
stroke-dashoffset: 0;
}
}
.s018-loader.paused,
.s018-loader[data-paused="true"],
.s018-loader.paused .s018-beam,
.s018-loader[data-paused="true"] .s018-beam {
animation-play-state: paused !important;
}
@media screen and (prefers-reduced-motion: reduce) {
.s018-beam {
animation: none !important;
stroke-dasharray: none;
stroke-dashoffset: 0;
opacity: 0.6;
}
}
import React from 'react';
import './S-018.css';
export default function InfinityLoopLoader({
width = 84,
height = 48,
speed = 2,
color = '#38bdf8',
paused = false
}) {
const style = {
'--s018-width': `${width}px`,
'--s018-height': `${height}px`,
'--s018-speed': `${speed}s`,
'--s018-glow-color': color,
};
const path = "M25,25 C10,25 10,40 25,40 C40,40 60,10 75,10 C90,10 90,25 75,25 C60,25 40,40 25,40 C10,40 10,25 25,25 C40,25 60,40 75,40 C90,40 90,25 75,25 C60,25 40,10 25,10 C10,10 10,25 25,25 Z";
return (
<div
className={`s018-loader ${paused ? 'paused' : ''}`}
style={style}
role="status"
aria-label="Loading"
>
<span className="s018-sr-only">Loading</span>
<svg className="s018-svg" viewBox="0 0 100 50" aria-hidden="true">
<path className="s018-track" d={path} />
<path className="s018-beam" d={path} />
</svg>
</div>
);
}
.s018-loader {
width: var(--s018-width, 84px);
height: var(--s018-height, 48px);
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.s018-sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.s018-svg {
width: 100%;
height: 100%;
overflow: visible;
}
.s018-track {
fill: none;
stroke: var(--s018-track-color, rgba(148, 163, 184, 0.18));
stroke-width: var(--s018-stroke-width, 4px);
stroke-linecap: round;
}
.s018-beam {
fill: none;
stroke: var(--s018-glow-color, #38bdf8);
stroke-width: var(--s018-stroke-width, 4px);
stroke-linecap: round;
stroke-dasharray: 40 180;
stroke-dashoffset: 220;
filter: drop-shadow(0 0 6px var(--s018-glow-color, #38bdf8));
animation: s018-trace var(--s018-speed, 2s) linear infinite;
}
@keyframes s018-trace {
to {
stroke-dashoffset: 0;
}
}
.s018-loader.paused,
.s018-loader[data-paused="true"],
.s018-loader.paused .s018-beam,
.s018-loader[data-paused="true"] .s018-beam {
animation-play-state: paused !important;
}
@media screen and (prefers-reduced-motion: reduce) {
.s018-beam {
animation: none !important;
stroke-dasharray: none;
stroke-dashoffset: 0;
opacity: 0.6;
}
}
仕組みとカスタマイズHow It Works & Customization
仕組みHow it works
A dual-path SVG structure renders a faint static track path and an identical animated stroke with dashed offset to simulate orbital motion.
薄いガイドトラックと同一の前面パスを重ね、stroke-dashoffsetのキーフレーム移動によって光線が軌道を周回するイリュージョンを作ります。
カスタマイズ方法Customization
Adjust stroke width, speed, glow color, and container dimensions using scoped CSS variables or React component props.
CSSカスタムプロパティ(--s018-width, --s018-speed, --s018-glow-color)またはReact propsで速度やカラー、サイズを調整できます。
注意点Caveats
When resizing, ensure stroke-dasharray and total path length maintain proportional visibility.
極端に縮小した際のパスの視認性に留意し、コンテナのviewBox比率を崩さないよう設定してください。
よくある質問 Frequently Asked Questions
How can I change the glow intensity? グローの強さを変更するにはどうすればよいですか?
Modify the filter drop-shadow property or customize the --s018-glow-color variable.
filter の drop-shadow プロパティのぼかし半径を変更するか、--s018-glow-color 変数を調整してください。
Is the SVG path responsive? SVGパスはレスポンシブに対応していますか?
Yes, the viewBox coordinates scale smoothly to any container width and height.
はい、viewBox (0 0 100 50) により親コンテナの幅と高さに合わせて自動的にスケーリングされます。
AIへの指示テンプレート AI Prompt Template
以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.