init
This commit is contained in:
110
uni_modules/nutui-uni/components/countup/countup.ts
Normal file
110
uni_modules/nutui-uni/components/countup/countup.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import { commonProps, isBoolean, makeNumberProp, makeStringProp, truthProp } from '../_utils'
|
||||
|
||||
export const countupProps = {
|
||||
...commonProps,
|
||||
/**
|
||||
* @description 初始数字
|
||||
*/
|
||||
initNum: makeNumberProp(0),
|
||||
/**
|
||||
* @description 结束数字
|
||||
*/
|
||||
endNum: makeNumberProp(0),
|
||||
/**
|
||||
* @description 间隔数字,目前仅支持基础用法
|
||||
*/
|
||||
speed: makeNumberProp(1),
|
||||
/**
|
||||
* @description 保留小数点后几位
|
||||
*/
|
||||
toFixed: makeNumberProp(0),
|
||||
/**
|
||||
* @description 触发数字滚动的标识
|
||||
*/
|
||||
startFlag: truthProp,
|
||||
/**
|
||||
* @description 滚动一次运行时间
|
||||
*/
|
||||
during: makeNumberProp(1000),
|
||||
/**
|
||||
* @description 数字宽度,常用于自定义无缝滚动
|
||||
*/
|
||||
numWidth: makeNumberProp(20),
|
||||
/**
|
||||
* @description 数字高度,常用于自定义无缝滚动(抽奖功能必传)
|
||||
*/
|
||||
numHeight: makeNumberProp(20),
|
||||
scrolling: Boolean,
|
||||
/**
|
||||
* @description 要变化的数字(用于自定义图片,`initNum`、`endNum` 在此无效)
|
||||
*/
|
||||
customChangeNum: makeNumberProp(1),
|
||||
/**
|
||||
* @description 自定义图片(建议使用雪碧图实现,使用抽奖功能必须使用雪碧图)
|
||||
*/
|
||||
customBgImg: makeStringProp(''),
|
||||
/**
|
||||
* @description 图片中数字之间可能会存在间距
|
||||
*/
|
||||
customSpacNum: makeNumberProp(0),
|
||||
/**
|
||||
* @description 抽奖功能传 machine,可选值为 `machine` `' '`
|
||||
*/
|
||||
type: makeStringProp(''),
|
||||
/**
|
||||
* @description 奖品个数,一共多少个奖品,必传
|
||||
*/
|
||||
machinePrizeNum: makeNumberProp(0),
|
||||
/**
|
||||
* @description 抽奖位,即滚动几个,必传
|
||||
*/
|
||||
machineNum: makeNumberProp(3),
|
||||
/**
|
||||
* @description 中奖图标,图标在雪碧图中的位置
|
||||
*/
|
||||
machinePrizeLevel: makeNumberProp(0),
|
||||
/**
|
||||
* @description 滚动圈数
|
||||
*/
|
||||
machineTurnMore: makeNumberProp(0),
|
||||
}
|
||||
|
||||
export type CountUpProps = ExtractPropTypes<typeof countupProps>
|
||||
|
||||
export const countupEmits = {
|
||||
scrollEnd: (val?: boolean) => isBoolean(val) || val === undefined,
|
||||
}
|
||||
|
||||
export type CountUpEmits = typeof countupEmits
|
||||
|
||||
export interface IData {
|
||||
valFlag: boolean
|
||||
current: number
|
||||
sortFlag: string
|
||||
initDigit1: number
|
||||
initDigit2: number
|
||||
to0_10: number[]
|
||||
to10_0: Array<number>
|
||||
timer: null | any
|
||||
totalCount: number // 正整数
|
||||
pointNum: number // 小数位
|
||||
numberVal: number // 数字
|
||||
num_total_len: number // 数字长度
|
||||
relNum: number // 去除小数点
|
||||
customNumber: number
|
||||
prizeLevelTrun: number
|
||||
prizeY: Array<any>
|
||||
prizeYPrev: Array<any>
|
||||
// machineTransition: 'none',
|
||||
finshMachine: number
|
||||
notPrize: Array<any>
|
||||
typeMachine: string
|
||||
}
|
||||
|
||||
export interface CountUpInst {
|
||||
/**
|
||||
* @description 抽奖
|
||||
*/
|
||||
machineLuck: () => void
|
||||
}
|
||||
575
uni_modules/nutui-uni/components/countup/countup.vue
Normal file
575
uni_modules/nutui-uni/components/countup/countup.vue
Normal file
@@ -0,0 +1,575 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineComponent, nextTick, onMounted, onUnmounted, reactive, watch } from 'vue'
|
||||
import { PREFIX } from '../_constants'
|
||||
import { useExtend } from '../_hooks'
|
||||
import { cloneDeep, getMainClass } from '../_utils'
|
||||
import type { IData } from './countup'
|
||||
import { countupEmits, countupProps } from './countup'
|
||||
|
||||
const props = defineProps(countupProps)
|
||||
const emit = defineEmits(countupEmits)
|
||||
defineExpose({ machineLuck })
|
||||
const classes = computed(() => {
|
||||
return getMainClass(props, componentName)
|
||||
})
|
||||
const data = reactive<IData>({
|
||||
valFlag: false,
|
||||
current: 0,
|
||||
sortFlag: 'add',
|
||||
initDigit1: 0,
|
||||
initDigit2: 0,
|
||||
to0_10: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
|
||||
to10_0: [0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1],
|
||||
timer: null,
|
||||
totalCount: 0, // 正整数
|
||||
pointNum: 0, // 小数位
|
||||
numberVal: 0, // 数字
|
||||
num_total_len: 0, // 数字长度
|
||||
relNum: 0, // 去除小数点
|
||||
customNumber: 1,
|
||||
prizeLevelTrun: 0,
|
||||
prizeY: [],
|
||||
prizeYPrev: [],
|
||||
// machineTransition: 'none',
|
||||
finshMachine: 0,
|
||||
notPrize: [],
|
||||
typeMachine: '',
|
||||
})
|
||||
const { startFlag, scrolling, customBgImg, type } = reactive(props)
|
||||
watch(
|
||||
() => props.customChangeNum,
|
||||
(count, prevCount) => {
|
||||
clearIntervalTime()
|
||||
// data.customNumber = count;
|
||||
countGo(0)
|
||||
},
|
||||
)
|
||||
watch(
|
||||
() => props.machinePrizeLevel,
|
||||
(count, prevCount) => {
|
||||
data.prizeLevelTrun = count
|
||||
},
|
||||
)
|
||||
watch(
|
||||
() => props.initNum,
|
||||
(count, prevCount) => {
|
||||
data.current = count
|
||||
data.valFlag = false
|
||||
valChange()
|
||||
},
|
||||
)
|
||||
watch(
|
||||
() => props.endNum,
|
||||
(count, prevCount) => {
|
||||
data.current = props.initNum
|
||||
data.valFlag = false
|
||||
valChange()
|
||||
},
|
||||
)
|
||||
function valChange() {
|
||||
if (data.valFlag)
|
||||
return false
|
||||
|
||||
if (startFlag) {
|
||||
if (scrolling || customBgImg) {
|
||||
if (type !== 'machine')
|
||||
countGo()
|
||||
}
|
||||
else {
|
||||
countChange()
|
||||
setTimeout(() => {
|
||||
data.valFlag = true
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 清空定时器
|
||||
function clearIntervalTime() {
|
||||
clearInterval(Number(data.timer))
|
||||
data.timer = null
|
||||
}
|
||||
// 精确计算
|
||||
function calculation(num1: number, num2: number, type: string) {
|
||||
const num1Digits = (num1.toString().split('.')[1] || '').length
|
||||
const num2Digits = (num2.toString().split('.')[1] || '').length
|
||||
const baseNum = 10 ** Math.max(num1Digits, num2Digits)
|
||||
if (type === '-') {
|
||||
const n = Number((num1 * baseNum - num2 * baseNum).toFixed(0))
|
||||
return n / baseNum
|
||||
}
|
||||
else {
|
||||
const m = Number((num1 * baseNum + num2 * baseNum).toFixed(0))
|
||||
return m / baseNum
|
||||
}
|
||||
}
|
||||
// 数字滚动-top值
|
||||
function topNumber(index: number) {
|
||||
const { num_total_len, pointNum, initDigit1, initDigit2, sortFlag } = data
|
||||
const idx1
|
||||
= sortFlag === 'add' || sortFlag === 'equal'
|
||||
? String(initDigit2)[index - (num_total_len - pointNum)]
|
||||
: 10 - Number(String(initDigit2)[index - (num_total_len - pointNum)])
|
||||
const idx2
|
||||
= sortFlag === 'add' || sortFlag === 'equal' ? String(initDigit1)[index] : 10 - Number(String(initDigit1)[index])
|
||||
let num
|
||||
= index > num_total_len - pointNum - 1
|
||||
? `${-idx1 * 100}%`
|
||||
: index <= String(initDigit1).length - 1
|
||||
? `${-idx2 * 100}%`
|
||||
: 0
|
||||
if (num === '-1000%')
|
||||
num = 0
|
||||
|
||||
return num
|
||||
}
|
||||
// 数字滚动-到哪里了
|
||||
function turnNumber(index: number) {
|
||||
const { num_total_len, pointNum, initDigit1, initDigit2, sortFlag } = data
|
||||
const idx1 = String(initDigit2)[index - (num_total_len - pointNum)]
|
||||
const num
|
||||
= index > num_total_len - pointNum - 1
|
||||
? idx1 || 0
|
||||
: index <= String(initDigit1).length - 1
|
||||
? String(initDigit1)[index]
|
||||
: 0
|
||||
return num
|
||||
}
|
||||
// 基础用法
|
||||
function countChange() {
|
||||
const { endNum, initNum, speed, toFixed } = props
|
||||
const countTimer = setInterval(() => {
|
||||
if (initNum > endNum) {
|
||||
// 减少
|
||||
if (data.current <= endNum || data.current <= speed) {
|
||||
// 数字减小,有可能导致current小于speed
|
||||
data.current = Number(endNum.toFixed(toFixed))
|
||||
clearInterval(countTimer)
|
||||
emit('scrollEnd')
|
||||
data.valFlag = false
|
||||
}
|
||||
else {
|
||||
data.current = Number((Number.parseFloat(String(data.current)) - Number.parseFloat(String(speed))).toFixed(toFixed))
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 增加
|
||||
if (data.current >= endNum) {
|
||||
data.current = Number(endNum.toFixed(toFixed))
|
||||
clearInterval(countTimer)
|
||||
emit('scrollEnd')
|
||||
data.valFlag = false
|
||||
}
|
||||
else {
|
||||
data.current = Number((Number.parseFloat(String(data.current)) + Number.parseFloat(String(speed))).toFixed(toFixed))
|
||||
}
|
||||
}
|
||||
}, props.during)
|
||||
}
|
||||
function countGo(flag?: number): void {
|
||||
let { initNum, endNum, toFixed, customBgImg } = props
|
||||
if (customBgImg)
|
||||
initNum = props.customChangeNum
|
||||
|
||||
// --------------
|
||||
let startNumber1, startNumber2, endNumber1, endNumber2
|
||||
if (initNum !== 0) {
|
||||
if (toFixed !== 0)
|
||||
initNum = Number(initNum.toFixed(toFixed))
|
||||
|
||||
if (String(initNum).includes('.')) {
|
||||
startNumber1 = String(initNum).split('.')[0].length
|
||||
startNumber2 = String(initNum).split('.')[1].length
|
||||
}
|
||||
else {
|
||||
startNumber1 = String(initNum).length
|
||||
startNumber2 = 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
startNumber1 = 1
|
||||
startNumber2 = 0
|
||||
}
|
||||
if (endNum !== 0) {
|
||||
if (toFixed !== 0)
|
||||
endNum = Number(endNum.toFixed(toFixed))
|
||||
|
||||
if (String(endNum).includes('.')) {
|
||||
endNumber1 = String(endNum).split('.')[0].length
|
||||
endNumber2 = String(endNum).split('.')[1].length
|
||||
}
|
||||
else {
|
||||
endNumber1 = String(endNum).length
|
||||
endNumber2 = 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
endNumber1 = 1
|
||||
endNumber2 = 0
|
||||
}
|
||||
const len1 = startNumber1 >= endNumber1 ? startNumber1 : endNumber1
|
||||
const len2 = startNumber2 >= endNumber2 ? startNumber2 : endNumber2
|
||||
data.num_total_len = len1 + len2
|
||||
|
||||
data.pointNum = len2
|
||||
|
||||
// --------------
|
||||
if (initNum > endNum) {
|
||||
// 减少
|
||||
data.sortFlag = 'reduce'
|
||||
data.to0_10 = [0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
data.totalCount = calculation(initNum, endNum, '-')
|
||||
data.numberVal = Number(String(initNum))
|
||||
}
|
||||
else if (initNum < endNum) {
|
||||
// 增加
|
||||
data.sortFlag = 'add'
|
||||
data.to0_10 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
|
||||
data.totalCount = calculation(endNum, initNum, '-')
|
||||
data.numberVal = Number(String(endNum))
|
||||
}
|
||||
else {
|
||||
data.sortFlag = 'equal'
|
||||
}
|
||||
// 将小数位数计算后,补0
|
||||
let unit = 1
|
||||
for (let i = 0; i < data.pointNum; i++)
|
||||
unit *= 10
|
||||
|
||||
const rel_big = data.numberVal * unit // 去除小数点后的数,unit几个零表示有几个小数
|
||||
data.relNum = rel_big
|
||||
// this.totalCount = rel_big;
|
||||
if (toFixed !== 0) {
|
||||
// 计算小数点后的位数,小数位
|
||||
data.pointNum = String(data.numberVal).split('.')[1] ? String(data.numberVal).split('.')[1].length : 0
|
||||
// 数字长度
|
||||
data.num_total_len = String(rel_big).length
|
||||
}
|
||||
if (String(initNum).includes('.')) {
|
||||
const n = String(initNum).split('.')
|
||||
data.initDigit1 = Number(n[0])
|
||||
data.initDigit2 = Number(n[1])
|
||||
}
|
||||
else {
|
||||
data.initDigit1 = initNum
|
||||
data.initDigit2 = 0
|
||||
}
|
||||
|
||||
if (scrolling && !customBgImg) {
|
||||
// #ifdef H5
|
||||
// 数字都是从小加到大的,所以我们循环转动最后一个数字,传入最后一个数字的DOM
|
||||
nextTick(() => {
|
||||
if (data.sortFlag === 'equal')
|
||||
return false
|
||||
|
||||
const refsDom: HTMLCollectionOf<Element> = document.getElementsByClassName('nut-countup__number-item')
|
||||
|
||||
const element = refsDom[data.num_total_len - 1]
|
||||
runTurn(element)
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
else {
|
||||
if (flag !== 0)
|
||||
imgNumberScroll()
|
||||
}
|
||||
}
|
||||
function runTurn(el: Element) {
|
||||
clearIntervalTime()
|
||||
let m = 1
|
||||
if (data.pointNum !== 0)
|
||||
m = 1 / 10 ** data.pointNum;
|
||||
|
||||
// 设置定时器
|
||||
(data.timer as any) = setInterval(() => {
|
||||
runStep(el)
|
||||
data.totalCount = calculation(data.totalCount, m, '-')
|
||||
// that.totalCount--;
|
||||
if (data.totalCount <= 0) {
|
||||
clearIntervalTime()
|
||||
emit('scrollEnd')
|
||||
data.valFlag = false
|
||||
}
|
||||
}, props.during)
|
||||
}
|
||||
|
||||
function runStep(el: any) {
|
||||
// let currentTurn = el.getAttribute('turn-number');
|
||||
const currentTurn = el.style.all
|
||||
let turningNum: number
|
||||
if (data.sortFlag === 'add')
|
||||
turningNum = Number.parseInt(String(currentTurn)) + 1
|
||||
else
|
||||
turningNum = Number.parseInt(String(currentTurn)) - 1 >= 0 ? Number.parseInt(String(currentTurn)) - 1 : 9
|
||||
|
||||
// el.setAttribute('turn-number', String(turningNum));
|
||||
el.style.all = String(turningNum)
|
||||
|
||||
if (el.style.transition === 'none' || turningNum === 1 || !el.style.transition)
|
||||
el.style.transition = `all linear ${props.during}ms`
|
||||
|
||||
if (turningNum === 10 || (data.sortFlag === 'reduce' && turningNum === 0)) {
|
||||
let timeOut: any = null
|
||||
// el.style.top = `-${turningNum * 100}%`;
|
||||
el.style.top = `-${data.sortFlag === 'add' ? turningNum * 100 : (10 - turningNum) * 100}%`
|
||||
// el.setAttribute('turn-number', '0');
|
||||
el.style.all = '0'
|
||||
timeOut = setTimeout(() => {
|
||||
timeOut && clearTimeout(timeOut)
|
||||
el.style.transition = 'none'
|
||||
el.style.top = '0'
|
||||
// 前面数字的滚动,用于递增
|
||||
if (turningNum === 10) {
|
||||
if (el.previousSibling)
|
||||
runStep(el.previousSibling as HTMLElement)
|
||||
}
|
||||
}, 0.975 * props.during)
|
||||
}
|
||||
else {
|
||||
// el.style.top = `-${(10-turningNum)*100}%`;
|
||||
el.style.top = `-${data.sortFlag === 'add' ? turningNum * 100 : (10 - turningNum) * 100}%`
|
||||
}
|
||||
// 用于递减的时候
|
||||
if (el.style.top === '-100%' && data.sortFlag === 'reduce')
|
||||
runStep(el.previousSibling as HTMLElement)
|
||||
}
|
||||
// 自定义图片
|
||||
function imgNumberScroll() {
|
||||
let m = 1
|
||||
if (data.pointNum !== 0)
|
||||
m = 10 ** data.pointNum
|
||||
// #ifdef H5
|
||||
nextTick(() => {
|
||||
const f = document.getElementsByClassName('nut-countup__numberimg')[0]
|
||||
// setTimeout(() => {
|
||||
// data.relNum = calculation(data.relNum, m * props.speed, '+');
|
||||
// }, props.during);
|
||||
f.addEventListener('webkitTransitionEnd', () => {
|
||||
emit('scrollEnd')
|
||||
data.valFlag = false
|
||||
// setTimeout(() => {
|
||||
// data.relNum = calculation(data.relNum, m * props.speed, '+');
|
||||
// }, props.during);
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
// 不中奖设置随机数
|
||||
function generateRandom() {
|
||||
data.notPrize = []
|
||||
while (data.notPrize.length < 3) {
|
||||
const rand: number = Math.floor(Math.random() * props.machinePrizeNum + 1)
|
||||
if (!data.notPrize.includes(rand))
|
||||
data.notPrize.push(rand)
|
||||
}
|
||||
}
|
||||
// 抽奖
|
||||
function machineLuck() {
|
||||
const machineTurnMoreNum = props.machineTurnMore < 0 ? 0 : props.machineTurnMore
|
||||
const distance = props.numHeight * props.machinePrizeNum // 所有奖品的高度,雪碧图的高度
|
||||
if (data.prizeLevelTrun < 0)
|
||||
generateRandom()
|
||||
|
||||
for (let i = 0; i < props.machineNum; i++) {
|
||||
setTimeout(() => {
|
||||
const turn = distance * (i + 1 + Number.parseFloat(String(machineTurnMoreNum)))
|
||||
if (data.prizeYPrev.length !== 0) {
|
||||
// this.machineTransition = 'none';
|
||||
// console.log(this.prizeYPrev[i]-(this.numHeight * this.machinePrizeNum));
|
||||
// this.$set(data.prizeY, i, data.prizeYPrev[i]);
|
||||
data.prizeY[i] = data.prizeYPrev[i]
|
||||
}
|
||||
const local = data.prizeYPrev[i] ? data.prizeYPrev[i] : 0
|
||||
let newLocation
|
||||
= turn + local + (props.machinePrizeNum - data.prizeLevelTrun + 1) * props.numHeight + (distance - local)
|
||||
if (data.prizeLevelTrun < 0)
|
||||
newLocation += props.numHeight * data.notPrize[i]
|
||||
|
||||
scrollTime(
|
||||
i,
|
||||
// parseFloat((this.machinePrizeNum-(this.prizeLevelTrun-1))*this.numHeight + turn + local),
|
||||
newLocation,
|
||||
local,
|
||||
)
|
||||
}, 500 * i)
|
||||
}
|
||||
}
|
||||
useExtend({ machineLuck })
|
||||
function scrollTime(index: number, total: number, num: number) {
|
||||
// this.machineTransition = `all linear ${this.during/this.machinePrizeNum}ms`;
|
||||
let t: any = setInterval(() => {
|
||||
if (num <= total) {
|
||||
num += 10
|
||||
data.prizeY[index] = Number.parseFloat(String(num))
|
||||
}
|
||||
else {
|
||||
clearInterval(t)
|
||||
t = null
|
||||
data.finshMachine += 1
|
||||
data.prizeY[index] = total
|
||||
if (data.finshMachine === props.machineNum) {
|
||||
const distance = props.numHeight * props.machinePrizeNum
|
||||
data.prizeYPrev = []
|
||||
const prevAry = cloneDeep(data.prizeY)
|
||||
prevAry.forEach((item: any) => {
|
||||
let n = item
|
||||
while (n > distance)
|
||||
n -= distance
|
||||
|
||||
data.prizeYPrev.push(n)
|
||||
})
|
||||
setTimeout(() => {
|
||||
data.finshMachine = 0
|
||||
if (data.prizeLevelTrun < 0) {
|
||||
emit('scrollEnd', false)
|
||||
data.valFlag = false
|
||||
}
|
||||
else {
|
||||
emit('scrollEnd', true)
|
||||
data.valFlag = false
|
||||
}
|
||||
}, 130)
|
||||
}
|
||||
}
|
||||
}, 30)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
data.current = props.initNum
|
||||
nextTick(() => {
|
||||
valChange()
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
clearIntervalTime()
|
||||
data.timer = null
|
||||
})
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const componentName = `${PREFIX}-countup`
|
||||
|
||||
export default defineComponent({
|
||||
name: componentName,
|
||||
options: {
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view :class="classes" :style="customStyle">
|
||||
<template v-if="customBgImg !== ''">
|
||||
<template v-if="type === 'machine'">
|
||||
<view class="nut-countup__machine" :style="{ height: `${numHeight}px` }">
|
||||
<view
|
||||
v-for="(val, index) of machineNum"
|
||||
:key="`mImg${index}`"
|
||||
class="nut-countup__machine-item"
|
||||
:style="{
|
||||
width: `${numWidth}px`,
|
||||
height: `${numHeight}px`,
|
||||
background: `url(${customBgImg}) `,
|
||||
backgroundPosition: `0 ${data.prizeY[index]}px`,
|
||||
}"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="nut-countup__numberimg" :style="{ height: `${numHeight}px` }">
|
||||
<view
|
||||
v-for="(val, index) of data.num_total_len"
|
||||
:key="`cImg${index}`"
|
||||
class="nut-countup__numberimg__item"
|
||||
:style="{
|
||||
width: `${numWidth}px`,
|
||||
height: `${numHeight}px`,
|
||||
left:
|
||||
`${numWidth
|
||||
* (index > data.num_total_len - data.pointNum - 1
|
||||
? index === data.num_total_len - data.pointNum
|
||||
? index * 1.5
|
||||
: index * 1.3
|
||||
: index)
|
||||
}px`,
|
||||
backgroundImage: `url(${customBgImg})`,
|
||||
backgroundPosition:
|
||||
`0 ${-(+String(data.relNum)[index] * numHeight + customSpacNum * +String(data.relNum)[index])}px`,
|
||||
transition: `all linear ${during / 10}ms`,
|
||||
}"
|
||||
/>
|
||||
<view
|
||||
v-if="data.pointNum > 0"
|
||||
class="nut-countup-pointstyl"
|
||||
:style="{
|
||||
width: `${numWidth / 2}px`,
|
||||
bottom: 0,
|
||||
left: `${numWidth * (data.num_total_len - data.pointNum) * 1.1}px`,
|
||||
fontSize: '30px',
|
||||
}"
|
||||
>
|
||||
.
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view
|
||||
v-if="scrolling"
|
||||
class="nut-countup__number"
|
||||
:style="{
|
||||
width: `${numWidth * data.num_total_len + numWidth / 3}px`,
|
||||
height: `${numHeight}px`,
|
||||
lineHeight: `${numHeight}px`,
|
||||
}"
|
||||
>
|
||||
<view
|
||||
v-for="(val, index) of data.num_total_len"
|
||||
:key="val"
|
||||
class="nut-countup__number-item"
|
||||
:style="{
|
||||
all: turnNumber(index) as any,
|
||||
top: topNumber(index),
|
||||
left: `${numWidth * (index > data.num_total_len - data.pointNum - 1 ? index * 1.1 : index)}px`,
|
||||
}"
|
||||
:turn-number="turnNumber(index)"
|
||||
>
|
||||
<view
|
||||
v-for="(item, idx) of data.to0_10"
|
||||
:key="`dote${idx}`"
|
||||
class="nut-countup__number-item__span"
|
||||
:style="{
|
||||
width: `${numWidth}px`,
|
||||
height: `${numHeight}px`,
|
||||
lineHeight: `${numHeight}px`,
|
||||
}"
|
||||
>
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="data.pointNum > 0"
|
||||
class="nut-countup-pointstyl"
|
||||
:style="{
|
||||
width: `${numWidth / 3}px`,
|
||||
height: `${numHeight}px`,
|
||||
lineHeight: `${numHeight}px`,
|
||||
top: 0,
|
||||
left: `${numWidth * (data.num_total_len - data.pointNum)}px`,
|
||||
}"
|
||||
>
|
||||
.
|
||||
</view>
|
||||
</view>
|
||||
<template v-else>
|
||||
{{ data.current }}
|
||||
</template>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './index';
|
||||
</style>
|
||||
64
uni_modules/nutui-uni/components/countup/index.scss
Normal file
64
uni_modules/nutui-uni/components/countup/index.scss
Normal file
@@ -0,0 +1,64 @@
|
||||
.nut-theme-dark {
|
||||
.nut-countup {
|
||||
color: $dark-color;
|
||||
background: $dark-background;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-countup {
|
||||
display: block;
|
||||
padding: 5px 20px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
|
||||
.nut-countup__number {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
|
||||
.nut-countup__number-item {
|
||||
position: absolute;
|
||||
list-style: none;
|
||||
transition: none;
|
||||
|
||||
.nut-countup__number-item__span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-countup-pointstyl {
|
||||
position: absolute;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nut-countup__machine {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
||||
.nut-countup__machine-item {
|
||||
float: left;
|
||||
background-repeat: repeat-y;
|
||||
background-attachment: scroll;
|
||||
background-position: center 0;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-countup__numberimg {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
.nut-countup__numberimg__item {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 0;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
uni_modules/nutui-uni/components/countup/index.ts
Normal file
1
uni_modules/nutui-uni/components/countup/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type * from './countup'
|
||||
Reference in New Issue
Block a user