Circle リング状進捗バー - Vant 4
⭕ 紹介
Circle リング状進捗バーは優雅な時計の文字盤のようなもので、滑らかな弧で進捗状況を表現します 🕐。単なる進捗インジケーター以上のもので、スムーズなアニメーションとグラデーションカラーで、退屈な数字を見た目の美しい視覚体験に変えます。ファイルのダウンロード進捗、タスクの完了度、スキルの熟練度など、あらゆる場面で Circle はその独特なリングの魅力で、ユーザーが待つ間でも美しさを感じることができます ✨。
📦 導入
以下の方法でグローバルにコンポーネントを登録します。詳細な登録方法については、コンポーネントの登録を参照してください。
import { createApp } from 'vue';
import { Circle } from 'vant';
const app = createApp();
app.use(Circle);🎯 コードデモ
基本的な使い方
Circle の魅力はスマートなアニメーションシステムにあります 🎬!rate 属性は進捗バーの目標値を設定し、v-model:current-rate はアニメーションの進行状況をリアルタイムで追跡します。rate の値を変更すると、Circle は優雅なダンサーのように、speed で設定されたテンポで現在の位置から目標位置までゆっくりと動き、すべてのフレームが滑らかな美感で満たされ、待ち時間を楽しみに変えます!
<van-circle
v-model:current-rate="currentRate"
:rate="100"
:text="text"
:speed="100"
/>
```js
import { ref, computed } from 'vue';
export default {
setup() {
const currentRate = ref(0);
const text = computed(() => currentRate.value.toFixed(0) + '%');
return { text, currentRate };
},
};幅のカスタマイズ
進捗バーに個性を持たせたいですか?stroke-width 属性は魔法のブラシです 🎨!リングの太さを制御し、ブラシの筆触を調整するようなものです。細い優雅な線が好きでも、太く力強い線が好きでも、この属性で簡単に実現できます。デフォルト値の 40 はすでに完璧ですが、デザインのニーズに合わせて自由に調整できます!
<van-circle
v-model:current-rate="currentRate"
:rate="100"
:stroke-width="60"
:text="text"
:speed="100"
/>
`stroke-width` の単位は `px` ではありません。`stroke-width` と `px` の変換関係を知りたい場合は、次の数式で計算できます:
```js
// SVG の viewBox サイズ
const viewBox = 1000 + strokeWidth;
// Circle コンポーネントの幅、デフォルトは 100px
const circleWidth = 100;
// 最終的にレンダリングされる進捗バーの幅(px)
const pxWidth = (strokeWidth * circleWidth) / viewBox;色のカスタマイズ
色彩は Circle の魂です 🌈!color 属性を使用すると、進捗バーに好きな色を着せることができ、layer-color 属性は下のレイヤーの軌道を装飾します。舞台の照明を設定するように、適切な色の組み合わせで進捗バーをインターフェースの中で目立たせ、最も光る星にすることができます!
<van-circle
v-model:current-rate="currentRate"
:rate="100"
color="#ee0a24"
layer-color="#ebedf0"
:text="text"
:speed="100"
/>
### グラデーションカラー
よりクールな視覚効果を望んでいますか?`color` 属性はグラデーションの魔法もサポートしています ✨!オブジェクトを渡すだけで、ある色から別の色への滑らかな遷移を作り出し、進捗バーを虹のように鮮やかにすることができます!
```html
<van-circle
v-model:current-rate="currentRate"
:rate="100"
:color="gradientColor"
:text="text"
:speed="100"
/>
```js
import { ref } from 'vue';
export default {
setup() {
const currentRate = ref(0);
const gradientColor = {
'0%': '#3fecff',
'100%': '#6149f6',
};
return { currentRate, gradientColor };
},
};
### 反時計回り
時々、逆向きの美しさも特別な魅力があります 🔄!`clockwise` を `false` に設定すると、Circle はタイムスリップのように、反時計回りの方向で優雅に進捗を表示します。この独特なアニメーションの向きによって、アプリケーションに神秘的で創造的な雰囲気を加えることができます!
```html
<van-circle
v-model:current-rate="currentRate"
:rate="100"
:clockwise="false"
:text="text"
:speed="100"
/>
### サイズのカスタマイズ
サイズはあなた次第です!`size` 属性を使用すると、Circle の寸法を自由に調整できます 📏。精巧で小さなミニバージョンでも、目立つ大きなバージョンでも、あなたのインターフェースデザインのニーズに完全に適合します!
```html
<van-circle
v-model:current-rate="currentRate"
:rate="100"
size="120"
:text="text"
:speed="100"
/>
### 開始位置
進捗バーは必ず上部から始まる必要があると言ったことがありますか?Circle はあなたにもっと多くの選択の自由を与えます 🧭!`start-position` 属性によって、進捗を上部、左、右、または下部の任意の位置から始めることができ、羅針盤のように、あなたが望むどの方向にも向けることができます!
```html
<van-circle
v-model:current-rate="currentRate"
:rate="100"
start-position="right"
:text="text"
:speed="100"
/>
## API
### Props
| パラメータ | 説明 | 型 | デフォルト値 |
| --- | --- | --- | --- |
| v-model:current-rate | 現在の進捗 | *number* | \- |
| rate | 目標進捗 | *number \| string* | `100` |
| size | リングの直径、デフォルト単位は `px` | *number \| string* | `100px` |
| color | 進捗バーの色、オブジェクト形式でグラデーションを定義可能 | *string \| object* | `#1989fa` |
| layer-color | レイヤーの色 | *string* | `white` |
| fill | 塗りつぶしの色 | *string* | `none` |
| speed | アニメーション速度(単位: rate/s) | *number \| string* | `0` |
| text | テキスト | *string* | \- |
| stroke-width | 進捗バーの幅 | *number \| string* | `40` |
| stroke-linecap | 進捗バーの端点の形状、オプション: `square`・`butt` | *string* | `round` |
| clockwise | 時計回りに増加するかどうか | *boolean* | `true` |
| start-position | 進捗の開始位置、オプション: `left`・`right`・`bottom` | *CircleStartPosition* | `top` |
### Slots
| 名前 | 説明 |
| --- | --- |
| default | カスタムテキストコンテンツ |
### 型定義
コンポーネントは以下の型定義をエクスポートします:
```ts
import type { CircleProps, CircleStartPosition } from 'vant';テーマカスタマイズ
スタイル変数
コンポーネントはカスタムスタイルに使用できる以下の CSS 変数を提供します。使用方法については、ConfigProvider コンポーネントを参照してください。
| 名前 | デフォルト値 | 説明 |
|---|---|---|
| --van-circle-size | 100px | - |
| --van-circle-color | var(--van-primary-color) | - |
| --van-circle-layer-color | var(--van-white) | - |
| --van-circle-text-color | var(--van-text-color) | - |
| --van-circle-text-font-weight | var(--van-font-bold) | - |
| --van-circle-text-font-size | var(--van-font-size-md) | - |
| --van-circle-text-line-height | var(--van-line-height-md) | - |
ベストプラクティス
進捗表示の原則
リング状進捗バーをデザインする際は、以下の原則に従うべきです 🎯:
<!-- ✅ 推奨:明確な進捗情報の表示 -->
<van-circle
v-model:current-rate="currentRate"
:rate="targetRate"
:speed="100"
:text="progressText"
color="#1989fa"
/>
<!-- ❌ 避ける:速すぎるアニメーション速度はユーザー体験に悪影響 -->
<van-circle
:rate="100"
:speed="1000"
text="瞬時に完了"
/>アニメーション速度の制御
適切なアニメーション速度はユーザー体験を向上させます ⚡:
// ✅ 推奨:進捗の差分に応じてアニメーション速度を調整
const calculateSpeed = (currentRate, targetRate) => {
const diff = Math.abs(targetRate - currentRate);
if (diff <= 10) return 50; // 小さな変化、低速アニメーション
if (diff <= 50) return 100; // 中程度の変化、中速アニメーション
return 200; // 大きな変化、高速アニメーション
};
// 動的にアニメーション速度を調整
const animationSpeed = computed(() =>
calculateSpeed(currentRate.value, targetRate.value)
);テキストコンテンツのデザイン
<!-- 多様なテキスト表示 -->
<van-circle v-model:current-rate="currentRate" :rate="80">
<template #default>
<div class="circle-text">
<div class="percentage">{{ Math.round(currentRate) }}%</div>
<div class="label">完了済み</div>
</div>
</template>
</van-circle>
<style>
.circle-text {
text-align: center;
}
.percentage {
font-size: 18px;
font-weight: bold;
color: #1989fa;
}
.label {
font-size: 12px;
color: #969799;
margin-top: 4px;
}
</style>パフォーマンス最適化のヒント
アニメーションのパフォーマンス最適化
リング状進捗バーのアニメーションパフォーマンスを最適化する 🚀:
// ✅ 推奨:requestAnimationFrame を使用してアニメーションを最適化
const smoothProgress = ref(0);
const targetProgress = ref(0);
const animateProgress = () => {
const diff = targetProgress.value - smoothProgress.value;
if (Math.abs(diff) < 0.1) {
smoothProgress.value = targetProgress.value;
return;
}
smoothProgress.value += diff * 0.1;
requestAnimationFrame(animateProgress);
};
// 目標進捗の変化を監視
watch(targetProgress, () => {
animateProgress();
});メモリ管理
// コンポーネントがアンマウントされるときにタイマーをクリア
onUnmounted(() => {
if (animationTimer) {
clearInterval(animationTimer);
}
});デザインの推奨事項
ビジュアルデザイン
- サイズの選択:コンテンツの重要性に応じて適切なサイズを選択 📐
- 色の組み合わせ:ブランドカラーまたは意味的な色を使用 🎨
- コントラスト:進捗バーと背景の十分なコントラストを確保 👁️
- アニメーションの滑らかさ:アニメーションの連続性と自然さを維持 🌊
インタラクティブ体験
- 即時フィードバック:進捗の変化には即時の視覚的なフィードバックが必要 ⚡
- 明確な状態:異なる状態には明確な視覚的な区別が必要 🚦
- 完全な情報:必要な進捗情報と状態の説明を提供 📊
よくある質問の解決策
Q: セグメント化された進捗バーを実装するには?
<van-circle
v-model:current-rate="currentRate"
:rate="segmentRate"
:color="segmentColor"
:text="segmentText"
/>
<script>
const segments = [
{ rate: 25, color: '#ff4444', text: '初級' },
{ rate: 50, color: '#ffaa00', text: '中級' },
{ rate: 75, color: '#00aa00', text: '上級' },
{ rate: 100, color: '#0066ff', text: 'エキスパート' }
];
const currentSegment = computed(() =>
segments.find(seg => currentRate.value <= seg.rate) || segments[segments.length - 1]
);
const segmentRate = computed(() => currentSegment.value.rate);
const segmentColor = computed(() => currentSegment.value.color);
const segmentText = computed(() => currentSegment.value.text);
</script>Q: 複数の進捗バーの同期アニメーションを実装するには?
<div class="progress-group">
<van-circle
v-for="(item, index) in progressItems"
:key="index"
v-model:current-rate="item.currentRate"
:rate="item.targetRate"
:speed="animationSpeed"
:color="item.color"
:text="item.text"
/>
</div>
<script>
const startSyncAnimation = () => {
progressItems.forEach((item, index) => {
setTimeout(() => {
item.targetRate = item.finalRate;
}, index * 200); // アニメーションのタイミングをずらす
});
};
</script>Q: 進捗バーの一時停止と再開を実装するには?
const isPaused = ref(false);
const pausedRate = ref(0);
const pauseProgress = () => {
isPaused.value = true;
pausedRate.value = currentRate.value;
};
const resumeProgress = () => {
isPaused.value = false;
currentRate.value = pausedRate.value;
};
// 一時停止状態を監視
watch(isPaused, (paused) => {
if (paused) {
// アニメーションの一時停止ロジック
} else {
// アニメーションの再開ロジック
}
});高度な使用例
ダッシュボードスタイルの進捗バー
<template>
<div class="dashboard-circle">
<van-circle
v-model:current-rate="currentRate"
:rate="targetRate"
:size="200"
:stroke-width="20"
:color="dashboardColor"
layer-color="#f0f0f0"
start-position="bottom"
>
<div class="dashboard-content">
<div class="value">{{ Math.round(currentRate) }}</div>
<div class="unit">km/h</div>
<div class="label">現在の速度</div>
</div>
</van-circle>
</div>
</template>
<style>
.dashboard-content {
text-align: center;
}
.value {
font-size: 32px;
font-weight: bold;
color: #333;
}
.unit {
font-size: 14px;
color: #666;
margin-top: 4px;
}
.label {
font-size: 12px;
color: #999;
margin-top: 8px;
}
</style>スキル熟練度の表示
<template>
<div class="skill-progress">
<van-circle
v-for="skill in skills"
:key="skill.name"
v-model:current-rate="skill.currentRate"
:rate="skill.level"
:size="80"
:color="skill.color"
:text="skill.name"
class="skill-item"
/>
</div>
</template>
<script>
const skills = ref([
{ name: 'Vue', level: 90, currentRate: 0, color: '#4fc08d' },
{ name: 'React', level: 75, currentRate: 0, color: '#61dafb' },
{ name: 'Angular', level: 60, currentRate: 0, color: '#dd0031' }
]);
</script>関連コンポーネント
- Progress 進捗バー - 線形の進捗表示
- Loading ローディング - ローディング状態の指示
- Skeleton スケルトンスクリーン - コンテンツ読み込み中のプレースホルダー
- Steps ステップバー - プロセスフローの表示