Skip to content

Commit

Permalink
feat: new component CountTo
Browse files Browse the repository at this point in the history
  • Loading branch information
Aybrea committed Nov 20, 2024
1 parent 9e13dd0 commit d0fcf8a
Show file tree
Hide file tree
Showing 10 changed files with 354 additions and 27 deletions.
46 changes: 28 additions & 18 deletions packages/varlet-ui/src/count-to/CountTo.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<template>
<div :class="n()">
<div :style="{ transform: `translateX(${value}px)` }">{{ value }}: {{ state }}</div>
<button @click="start">Start</button>
<button @click="pause">Pause</button>
<button @click="reset">Reset</button>
<slot v-bind="numberData"> {{ numberData.value }} </slot>

Check warning on line 3 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L3

Added line #L3 was not covered by tests
</div>
</template>

<script lang="ts">
import { computed, defineComponent } from 'vue'
import { props } from './props'
import { defineComponent, computed, onMounted } from 'vue'
import { props, type NumberData } from './props'
import { createNamespace } from '../utils/components'
import { useMotion } from '@varlet/use'
import { floor } from '@varlet/shared'
Expand All @@ -19,33 +16,46 @@ const { name, n } = createNamespace('count-to')
export default defineComponent({
name,
props,
setup() {
setup(props) {

Check warning on line 19 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L19

Added line #L19 was not covered by tests
const {
value: _value,
state,
start,
pause,
reset,
reset: _reset,
} = useMotion({

Check warning on line 26 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L26

Added line #L26 was not covered by tests
from: 0,
to: 200,
duration: 2000,
from: Number(props.from),
to: Number(props.to),
duration: Number(props.duration),
timingFunction: props.timingFunction,
onFinished: props.onFinished,
})
const value = computed(() => floor(_value.value))
const numberData = computed<NumberData>(() => ({

Check warning on line 34 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L34

Added line #L34 was not covered by tests
value: floor(_value.value),
state: state.value,
}))
onMounted(() => {

Check warning on line 39 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L39

Added line #L39 was not covered by tests
if (props.autoStart) {
start()

Check warning on line 41 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L41

Added line #L41 was not covered by tests
}
})
function reset() {
_reset()

Check warning on line 46 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L45-L46

Added lines #L45 - L46 were not covered by tests
if (props.autoStart) {
start()

Check warning on line 48 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L48

Added line #L48 was not covered by tests
}
}
return {

Check warning on line 52 in packages/varlet-ui/src/count-to/CountTo.vue

View check run for this annotation

Codecov / codecov/patch

packages/varlet-ui/src/count-to/CountTo.vue#L52

Added line #L52 was not covered by tests
numberData,
n,
start,
pause,
reset,
state,
value,
}
},
})
</script>

<style lang="less">
@import './countTo';
</style>
2 changes: 0 additions & 2 deletions packages/varlet-ui/src/count-to/countTo.less

This file was deleted.

112 changes: 112 additions & 0 deletions packages/varlet-ui/src/count-to/docs/en-US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Number Animation

### Introduction

Display a number animation transitioning from a start value to a target value.

### Basic Usage

The `from` and `to` attributes specify the start and target values.

```html
<template>
<var-count-to :from="0" :to="123456" />
</template>
```

### Custom Duration

The `duration` attribute specifies the animation duration in milliseconds.

```html
<template>
<var-count-to :from="0" :to="123456" :duration="100000" />
</template>
```

### Custom Styles

The default scoped slot exposes the `state` and `value` properties, allowing you to customize styles through the slot.

```html
<template>
<var-count-to :from="0" :to="123456">
<template #default="{ state, value }">
<i>{{ state }}: {{ value.toLocaleString() }}</i>
</template>
</var-count-to>
</template>
```

### Custom Animation Curve

The `timing-function` attribute specifies the animation curve.

```html
<template>
<var-count-to :from="0" :to="123456" :timing-function="(t) => 1 - Math.pow(1 - t, 2)" />
</template>
```

### Manual Control

Use `ref` to get countTo instance, you can call the `start`, `pause`, and `reset` methods.

```html
<script setup>
import { ref } from 'vue'
const countToRef = ref()
</script>

<template>
<var-count-to :from="0" :to="123456" ref="countToRef" :auto-start="false" />
<var-row style="margin-top: 10px">
<var-button-group>
<var-button @click="countToRef.start()">{{ t('startText') }}</var-button>
<var-button @click="countToRef.pause()">{{ t('pauseText') }}</var-button>
<var-button @click="countToRef.reset()">{{ t('resetText') }}</var-button>
</var-button-group>
</var-row>
</template>
```

## API

### Properties

| Property | Description | Type | Default | --- |
| ------------ | ---------------------------------------- | ------------------ | ------- | --- |
| `from` | Start value | _number \| string_ | `0` |
| `to` | Target value | _number \| string_ | `0` |
| `duration` | Animation duration (ms) | _number \| string_ | `30000` |
| `auto-start` | Whether to start animation automatically | _boolean_ | `true` |

### Events

| Event Name | Description | Callback Parameters |
| ---------- | ----------------------------- | ------------------- |
| `finished` | Triggered when animation ends | `-` |

### Slots

| Slot Name | Description | Parameters |
| --------- | -------------- | ------------------------ |
| `default` | Custom content | `numberData: NumberData` |

### NumberData Format

| Name | Description | Type |
| ------- | ---------------------- | -------------------------------------------------- |
| `value` | Current value | `number` |
| `state` | Current playing state | `'running' \| 'paused' \| 'pending' \| 'finished'` |

### Methods

Use ref to get CountTo instance and call instance methods.

| Method | Description | arguments | Return |
| ------- | ------------------------------------------------------------------------------------ | --------- | ------ |
| `start` | Start the animation | `-` | `-` |
| `pause` | Pause the animation | `-` | `-` |
| `reset` | Reset the animation. If `auto-start` is `true`, the animation will restart automatically | `-` | `-` |
112 changes: 112 additions & 0 deletions packages/varlet-ui/src/count-to/docs/zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# 数字动画

### 介绍

用于展示起始数值到目标数值的数字动画。

### 基本使用

通过 `from``to` 属性可以指定起始数值和目标数值。

```html
<template>
<var-count-to :from="0" :to="123456" />
</template>
```

### 自定义时长

通过 `duration` 属性可以指定动画时长(单位为毫秒)。

```html
<template>
<var-count-to :from="0" :to="123456" :duration="100000" />
</template>
```

### 自定义样式

默认作用域插槽暴露了 `state``value` 两个属性,可以通过插槽自定义样式。

```html
<template>
<var-count-to :from="0" :to="123456">
<template #default="{ state, value }">
<i>{{ state }}: {{ value.toLocaleString() }}</i>
</template>
</var-count-to>
</template>
```

### 自定义动画曲线

通过 `timing-function` 属性可以指定动画曲线。

```html
<template>
<var-count-to :from="0" :to="123456" :timing-function="(t) => 1 - Math.pow(1 - t, 2)" />
</template>
```

### 手动控制

通过 ref 获取到组件实例后,可以调用 `start``pause``reset` 方法。

```html
<script setup>
import { ref } from 'vue'
const countToRef = ref()
</script>

<template>
<var-count-to :from="0" :to="123456" ref="countToRef" :auto-start="false" />
<var-row style="margin-top: 10px">
<var-button-group>
<var-button @click="countToRef.start()">{{ t('startText') }}</var-button>
<var-button @click="countToRef.pause()">{{ t('pauseText') }}</var-button>
<var-button @click="countToRef.reset()">{{ t('resetText') }} </var-button>
</var-button-group>
</var-row>
</template>
```

## API

### 属性

| 参数 | 说明 | 类型 | 默认值 |
| ------------ | -------------------------- | ------------------ | ------- |
| `from` | 起始值 | _number \| string_ | `0` |
| `to` | 目标值 | _number \| string_ | `0` |
| `duration` | 动画持续时间(单位:毫秒) | _number \| string_ | `30000` |
| `auto-start` | 是否自动开始播放动画 | _boolean_ | `true` |

### 事件

| 事件名 | 说明 | 回调参数 |
| ---------- | -------------- | -------- |
| `finished` | 动画结束时触发 | `-` |

### 插槽

| 插槽名 | 说明 | 参数 |
| --------- | ---------- | ------------------------ |
| `default` | 自定义内容 | `numberData: NumberData` |

### NumberData 格式

| 名称 | 说明 | 类型 |
| ------- | ------------ | -------------------------------------------------- |
| `value` | 当前数值 | `number` |
| `state` | 当前播放状态 | `'running' \| 'paused' \| 'pending' \| 'finished'` |

### 方法

通过 ref 可以获取到 CountDown 实例并调用实例方法.

| 方法名 | 说明 | 参数 | 返回值 |
| ------- | --------------------------------------------------------- | ---- | ------ |
| `start` | 开始倒计时 | `-` | `-` |
| `pause` | 暂停倒计时 | `-` | `-` |
| `reset` | 重设动画,若 `auto-start``true`,重设后会自动开始播放 | `-` | `-` |
32 changes: 29 additions & 3 deletions packages/varlet-ui/src/count-to/example/index.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,37 @@
<script setup>
import { watchLang, AppType } from '@varlet/cli/client'
import { use } from './locale'
import { t, use } from './locale'
import { ref } from 'vue'
const countToRef = ref()
watchLang(use)
</script>

<template>
<app-type>Mobile phone example code</app-type>
<var-count-to />
<app-type>{{ t('basicUsage') }}</app-type>
<var-count-to :from="0" :to="123456" />

<app-type>{{ t('customDuration') }}</app-type>
<var-count-to :from="0" :to="123456" :duration="10000" />

<app-type>{{ t('customStyle') }}</app-type>
<var-count-to :from="0" :to="123456">
<template #default="{ state, value }">
<i>{{ state }}: {{ value.toLocaleString() }}</i>
</template>
</var-count-to>

<app-type>{{ t('customAnimationCurve') }}</app-type>
<var-count-to :from="0" :to="123456" :timing-function="(t) => 1 - Math.pow(1 - t, 2)" />

<app-type>{{ t('manualControl') }}</app-type>
<var-count-to :from="0" :to="123456" ref="countToRef" :auto-start="false" />
<var-row style="margin-top: 10px">
<var-button-group>
<var-button @click="countToRef.start()">{{ t('startText') }}</var-button>
<var-button @click="countToRef.pause()">{{ t('pauseText') }}</var-button>
<var-button @click="countToRef.reset()">{{ t('resetText') }} </var-button>
</var-button-group>
</var-row>
</template>
9 changes: 8 additions & 1 deletion packages/varlet-ui/src/count-to/example/locale/en-US.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
export default {
// Example locale
basicUsage: 'Basic Usage',
customDuration: 'Custom Duration',
customStyle: 'Custom Style',
manualControl: 'Manual Control',
customAnimationCurve: 'Custom Animation Curve',
startText: 'Start',
pauseText: 'Pause',
resetText: 'Reset',
}
10 changes: 9 additions & 1 deletion packages/varlet-ui/src/count-to/example/locale/zh-CN.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
export default {
// Example locale
basicUsage: '基本使用',
customDuration: '自定义时长',
customStyle: '自定义样式',
manualControl: '手动控制',
customAnimationCurve: '自定义动画曲线',
startText: '开始',
pauseText: '暂停',
resetText: '重置',
autoStart: '自动开始',
}
Loading

0 comments on commit d0fcf8a

Please sign in to comment.