Skip to content

数值动画 NumberAnimation

赞助

数值播放动画

基本使用

Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { NumberAnimation } from 'vue-amazing-ui'
const numberAnimationRef = ref<InstanceType<typeof NumberAnimation> | null>(null)
</script>
<template>
  <Space vertical>
    <Statistic title="一个小目标" tabular-nums>
      <NumberAnimation ref="numberAnimationRef" :to="100000000.12345" :autoplay="false" />
    </Statistic>
    <Button type="primary" @click="numberAnimationRef?.play()">播放</Button>
  </Space>
</template>

精度

Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { NumberAnimation } from 'vue-amazing-ui'
const precision2Ref = ref<InstanceType<typeof NumberAnimation> | null>(null)
const precision3Ref = ref<InstanceType<typeof NumberAnimation> | null>(null)
</script>
<template>
  <Row>
    <Col :span="12">
      <Space vertical>
        <Statistic title="一个小目标" tabular-nums>
          <NumberAnimation ref="precision2Ref" :from="0.0" :to="100000000.12345" :precision="2" :autoplay="false" />
        </Statistic>
        <Button type="primary" @click="precision2Ref?.play()">播放</Button>
      </Space>
    </Col>
    <Col :span="12">
      <Space vertical>
        <Statistic title="一个小目标" tabular-nums>
          <NumberAnimation ref="precision3Ref" :to="100000000.12345" :precision="3" :autoplay="false" />
        </Statistic>
        <Button type="primary" @click="precision3Ref?.play()">播放</Button>
      </Space>
    </Col>
  </Row>
</template>

前缀 & 后缀

Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { NumberAnimation } from 'vue-amazing-ui'
const prefixRef = ref<InstanceType<typeof NumberAnimation> | null>(null)
const suffixRef = ref<InstanceType<typeof NumberAnimation> | null>(null)
</script>
<template>
  <Row>
    <Col :span="12">
      <Space vertical>
        <Statistic title="一个小目标" tabular-nums>
          <NumberAnimation ref="prefixRef" prefix="$" :from="0" :to="100000000" :autoplay="false" />
        </Statistic>
        <Button type="primary" @click="prefixRef?.play()">播放</Button>
      </Space>
    </Col>
    <Col :span="12">
      <Space vertical>
        <Statistic title="一个小目标" tabular-nums>
          <NumberAnimation ref="suffixRef" :from="0" :to="100000000" suffix="元" :autoplay="false" />
        </Statistic>
        <Button type="primary" @click="suffixRef?.play()">播放</Button>
      </Space>
    </Col>
  </Row>
</template>

千分位分隔符 & 小数点字符

Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { NumberAnimation } from 'vue-amazing-ui'
const separatorRef = ref<InstanceType<typeof NumberAnimation> | null>(null)
const plainRef = ref<InstanceType<typeof NumberAnimation> | null>(null)
</script>
<template>
  <Row>
    <Col :span="12">
      <Space vertical>
        <Statistic title="一个小目标" tabular-nums>
          <NumberAnimation
            ref="separatorRef"
            separator=";"
            decimal=","
            :precision="2"
            :from="0"
            :to="100000000.12345"
            :autoplay="false"
          />
        </Statistic>
        <Button type="primary" @click="separatorRef?.play()">播放</Button>
      </Space>
    </Col>
    <Col :span="12">
      <Space vertical>
        <Statistic title="一个小目标" tabular-nums>
          <NumberAnimation ref="plainRef" separator="" :precision="2" :from="0" :to="100000000.12345" :autoplay="false" />
        </Statistic>
        <Button type="primary" @click="plainRef?.play()">播放</Button>
      </Space>
    </Col>
  </Row>
</template>

自定义样式

Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { NumberAnimation } from 'vue-amazing-ui'
const styleRef = ref<InstanceType<typeof NumberAnimation> | null>(null)
</script>
<template>
  <Space vertical>
    <Statistic title="一个小目标" tabular-nums>
      <NumberAnimation
        ref="styleRef"
        :value-style="{ fontSize: '30px', fontWeight: 600, color: '#d4380d' }"
        :from="0"
        :to="100000000"
        :autoplay="false"
      />
    </Statistic>
    <Button type="primary" @click="styleRef?.play()">播放</Button>
  </Space>
</template>

播放和动画时间

一个小目标
0.00
播放
Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { NumberAnimation } from 'vue-amazing-ui'
const numberAnimationRef = ref<InstanceType<typeof NumberAnimation> | null>(null)
const from = ref(0)
const to = ref(100000000)
function onStarted() {
  console.log('started')
}
function onFinished() {
  console.log('finished')
  ;[from.value, to.value] = [to.value, from.value]
}
</script>
<template>
  <Space vertical>
    <Statistic title="一个小目标" tabular-nums>
      <NumberAnimation
        ref="numberAnimationRef"
        :from="from"
        :to="to"
        :duration="5000"
        :precision="2"
        :autoplay="false"
        @started="onStarted"
        @finished="onFinished"
      />
    </Statistic>
    <Button type="primary" @click="numberAnimationRef?.play()">播放</Button>
  </Space>
</template>

自动播放

autoplay:
一个小目标
0
Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
const autoPlay = ref(true)
const value = ref(100000000)
</script>
<template>
  <Space vertical>
    <Space align="center">autoplay:<Switch v-model="autoPlay" /></Space>
    <Statistic title="一个小目标" tabular-nums>
      <NumberAnimation :autoplay="autoPlay" :from="0" :to="value" />
    </Statistic>
  </Space>
</template>

动画过渡效果

预置曲线
贝塞尔控制点
缓动函数
easeInOutCubic
播放
easeInOutCubic
0
Show Code
vue
<script setup lang="ts">
import { ref, computed } from 'vue'
import { TransitionPresets } from '@vueuse/core'
import type { CubicBezierPoints } from '@vueuse/core'
import { NumberAnimation } from 'vue-amazing-ui'
import type { NumberAnimationEasingPreset, RadioOption, SelectOption } from 'vue-amazing-ui'
const easingRef = ref<InstanceType<typeof NumberAnimation> | null>(null)
const bezierEasing: CubicBezierPoints = [0.4, 0, 0.2, 1]
const customEasing = (t: number) => t * t
// easing 的三种取值形式
const easingCategory = ref<'preset' | 'bezier' | 'function'>('preset')
const easingCategoryOptions: RadioOption[] = [
  { label: '预置曲线', value: 'preset' },
  { label: '贝塞尔控制点', value: 'bezier' },
  { label: '缓动函数', value: 'function' }
]
const easingType = ref<NumberAnimationEasingPreset>('easeInOutCubic')
const easingOptions: SelectOption[] = Object.keys(TransitionPresets).map((preset) => ({ label: preset, value: preset }))
const selectedEasing = computed(() => {
  if (easingCategory.value === 'bezier') {
    return bezierEasing
  }
  if (easingCategory.value === 'function') {
    return customEasing
  }
  return easingType.value
})
const easingLabel = computed(() => {
  if (easingCategory.value === 'bezier') {
    return '贝塞尔控制点 [0.4, 0, 0.2, 1]'
  }
  if (easingCategory.value === 'function') {
    return '缓动函数 (t) => t * t'
  }
  return easingType.value
})
// 类别或预置名变化时重建组件,触发重新播放
const easingKey = computed(() => `${easingCategory.value}-${easingType.value}`)
</script>
<template>
  <Space vertical>
    <Space align="center">
      <Radio v-model:value="easingCategory" :options="easingCategoryOptions" button button-style="solid" />
      <Select v-if="easingCategory === 'preset'" v-model="easingType" :options="easingOptions" width="200" search />
      <Button type="primary" @click="easingRef?.play()">播放</Button>
    </Space>
    <Statistic :title="easingLabel" tabular-nums>
      <NumberAnimation
        :key="easingKey"
        ref="easingRef"
        :easing="selectedEasing"
        :from="0"
        :to="100000000"
        :duration="2000"
      />
    </Statistic>
  </Space>
</template>

APIs

NumberAnimation

参数说明类型默认值
from数值动画起始数值,未播放时展示值同步跟随该值number0
to数值目标值,autoplaytrue 时变更即重播,否则在下次播放时生效number1000
duration数值动画持续时间,单位 msnumber3000
autoplay是否自动开始动画(由 false 变为 true 时重新播放)booleantrue
precision精度,保留小数点后几位number0
prefix前缀stringundefined
suffix后缀stringundefined
separator千分位分隔符string','
decimal小数点字符string'.'
valueStyle数值文本样式CSSProperties{}
easing动画缓动曲线,除预置名称外还可传三次贝塞尔控制点数组或缓动函数NumberAnimationEasingPreset | CubicBezierPoints | EasingFunction'easeInOutCubic'

easing 的取值与动画驱动方法 transition 均来自 @vueuse/coreuseTransition 模块,其中 CubicBezierPoints 为三次贝塞尔控制点数组,EasingFunction(t: number) => number 缓动函数:

vue
<NumberAnimation :easing="[0.4, 0, 0.2, 1]" :to="1000" />
<NumberAnimation :easing="(t) => t * t" :to="1000" />

EasingPreset Type


预置名称源自 @vueuse/coreTransitionPresets

名称
NumberAnimationEasingPreset'linear' | 'easeInSine' | 'easeOutSine' | 'easeInOutSine' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' | 'easeInQuart' | 'easeOutQuart' | 'easeInOutQuart' | 'easeInQuint' | 'easeOutQuint' | 'easeInOutQuint' | 'easeInExpo' | 'easeOutExpo' | 'easeInOutExpo' | 'easeInCirc' | 'easeOutCirc' | 'easeInOutCirc' | 'easeInBack' | 'easeOutBack' | 'easeInOutBack'

Methods

名称说明类型
play播放动画(动画进行中调用会被忽略,播放结束后可重复调用重新播放)() => void

Events

名称说明类型
started动画开始播放() => void
finished动画播放完成() => void

Released under the MIT License.