Morphing Polygon Loader モーフィングポリゴンローダー
Smooth geometric shape-shifting loader with dynamic gradient rotation. CSSのborder-radiusとグラデーション遷移による美しい幾何学形状モーフィングローダー。
ライブデモ Live Demo
読み込み中... Loading...
概要・用途・特徴Overview, Usage & Features
何ができるかWhat it does
A geometric loader that smoothly morphs its boundary between circle, rounded box, and diamond shapes while rotating.
円、角丸正方形、ダイヤなどの幾何学形状の間を滑らかにモーフィングしながら回転するローダー演出です。
どこで使うかWhere to use
Ideal for design tool loading states, creative portfolios, generative AI waiting indicators, and brand splashes.
デザインツールの待機状態、クリエイティブポートフォリオ、生成AIのローディング、ブランドスプラッシュなどに適しています。
特徴Key features
Continuous border-radius transitions, animated gradient color shift, full accessibility with role="status", reduced-motion stabilization.
連続的なborder-radius遷移、グラデーション色相変化、role="status"対応のアクセシビリティ、prefers-reduced-motion時の静止サポート。
調整可能パラメータ Adjustable Parameters
| Parameter | Default | Description |
|---|---|---|
size | 56px | Width and height of the loader container |
speed | 3.6s | Full morphing cycle duration |
primary | #8b5cf6 | Primary gradient accent color |
実装コード Implementation Code
<div class="s017-loader" role="status" aria-label="Loading">
<span class="s017-sr-only">Loading</span>
<div class="s017-shape" aria-hidden="true"></div>
</div>
.s017-loader {
--s017-size: 56px;
--s017-speed: 3.6s;
--s017-primary: #8b5cf6;
--s017-secondary: #06b6d4;
position: relative;
width: var(--s017-size);
height: var(--s017-size);
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.s017-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;
}
.s017-shape {
width: 100%;
height: 100%;
background: linear-gradient(135deg, var(--s017-primary), var(--s017-secondary));
box-shadow: 0 0 20px rgba(139, 92, 246, 0.45);
animation: s017-morph var(--s017-speed) cubic-bezier(0.77, 0, 0.175, 1) infinite;
}
@keyframes s017-morph {
0% {
border-radius: 50%;
transform: rotate(0deg) scale(0.9);
}
25% {
border-radius: 12%;
transform: rotate(90deg) scale(1);
background: linear-gradient(135deg, var(--s017-secondary), #3b82f6);
}
50% {
border-radius: 50% 0 50% 0;
transform: rotate(180deg) scale(0.85);
background: linear-gradient(135deg, #3b82f6, #ec4899);
}
75% {
border-radius: 4px 50% 4px 50%;
transform: rotate(270deg) scale(1);
background: linear-gradient(135deg, #ec4899, var(--s017-primary));
}
100% {
border-radius: 50%;
transform: rotate(360deg) scale(0.9);
background: linear-gradient(135deg, var(--s017-primary), var(--s017-secondary));
}
}
.s017-loader.paused,
.s017-loader[data-paused="true"],
.s017-loader.paused .s017-shape,
.s017-loader[data-paused="true"] .s017-shape {
animation-play-state: paused !important;
}
@media screen and (prefers-reduced-motion: reduce) {
.s017-shape {
animation: none !important;
border-radius: 20%;
transform: none !important;
opacity: 0.85;
}
}
import React from 'react';
import './S-017.css';
export default function MorphingPolygonLoader({
size = 56,
speed = 3.6,
primaryColor = '#8b5cf6',
secondaryColor = '#06b6d4',
paused = false
}) {
const style = {
'--s017-size': `${size}px`,
'--s017-speed': `${speed}s`,
'--s017-primary': primaryColor,
'--s017-secondary': secondaryColor,
};
return (
<div
className={`s017-loader ${paused ? 'paused' : ''}`}
style={style}
role="status"
aria-label="Loading"
>
<span className="s017-sr-only">Loading</span>
<div className="s017-shape" aria-hidden="true" />
</div>
);
}
.s017-loader {
width: var(--s017-size, 56px);
height: var(--s017-size, 56px);
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.s017-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;
}
.s017-shape {
width: 100%;
height: 100%;
background: linear-gradient(135deg, var(--s017-primary, #8b5cf6), var(--s017-secondary, #06b6d4));
box-shadow: 0 0 20px rgba(139, 92, 246, 0.45);
animation: s017-morph var(--s017-speed, 3.6s) cubic-bezier(0.77, 0, 0.175, 1) infinite;
}
@keyframes s017-morph {
0% {
border-radius: 50%;
transform: rotate(0deg) scale(0.9);
}
25% {
border-radius: 12%;
transform: rotate(90deg) scale(1);
background: linear-gradient(135deg, var(--s017-secondary, #06b6d4), #3b82f6);
}
50% {
border-radius: 50% 0 50% 0;
transform: rotate(180deg) scale(0.85);
background: linear-gradient(135deg, #3b82f6, #ec4899);
}
75% {
border-radius: 4px 50% 4px 50%;
transform: rotate(270deg) scale(1);
background: linear-gradient(135deg, #ec4899, var(--s017-primary, #8b5cf6));
}
100% {
border-radius: 50%;
transform: rotate(360deg) scale(0.9);
background: linear-gradient(135deg, var(--s017-primary, #8b5cf6), var(--s017-secondary, #06b6d4));
}
}
.s017-loader.paused,
.s017-loader[data-paused="true"],
.s017-loader.paused .s017-shape,
.s017-loader[data-paused="true"] .s017-shape {
animation-play-state: paused !important;
}
@media screen and (prefers-reduced-motion: reduce) {
.s017-shape {
animation: none !important;
border-radius: 20%;
transform: none !important;
opacity: 0.85;
}
}
仕組みとカスタマイズHow It Works & Customization
仕組みHow it works
Interpolates eight distinct border-radius values across keyframe percentages, synchronized with 360-degree rotation and gradient adjustments.
キーフレームごとに異なるborder-radius値を滑らかに補間し、360度回転とグラデーションカラーの遷移を同期させています。
カスタマイズ方法Customization
Adjust size, speed, and accent colors via CSS variables or React component props.
CSSカスタムプロパティ(--s017-size, --s017-speed, --s017-primary, --s017-secondary)またはReactのpropsで自由に変更可能です。
注意点Caveats
Provide a descriptive aria-label and ensure high contrast against the parent container background.
背景色とのコントラスト比を確保し、aria-labelによる適切な支援技術向けテキストを設定してください。
よくある質問 Frequently Asked Questions
How can I customize the primary and secondary colors? プライマリカラーとセカンダリカラーを変更するにはどうすればよいですか?
Update the --s017-primary and --s017-secondary CSS custom properties or pass them as props in React.
CSSカスタムプロパティ --s017-primary と --s017-secondary を上書きするか、Reactのprops(primaryColor / secondaryColor)に指定してください。
Is this animation heavy on CPU performance? CPUパフォーマンスへの負荷は高いですか?
No, it animates GPU-accelerated transforms and border-radius on a single small DOM node.
いいえ、単一の小さなDOMノード上でGPU合成されるtransformとborder-radiusのみをアニメーションするため非常に軽量です。
AIへの指示テンプレート AI Prompt Template
以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.