Taro(React)实现具有滚动效果的倒数计时器

Taro(React)实现具有滚动效果的倒数计时器

在这里插入图片描述

Taro获取节点方法的封装

import Taro from "@tarojs/taro";
import { NodesRef } from "@tarojs/taro";

const selectorQueryClientRect = (selector:string) : Promise<NodesRef.BoundingClientRectCallbackResult> => {
    return new Promise(resolve => {
        const query = Taro.createSelectorQuery()
        query.select(selector).boundingClientRect((res: NodesRef.BoundingClientRectCallbackResult) => {
            resolve(res)
        }).exec()
    })
}

export {
    selectorQueryClientRect
}

子组件

在这里插入图片描述

import { View } from "@tarojs/components"
import Taro from "@tarojs/taro";
import React, { CSSProperties, useEffect, useImperativeHandle, useState } from "react"
import { selectorQueryClientRect } from '../../util'
import "./index.css"

// props的接口
interface HPickItemProps {
    list: Array<any>,
    hclass?: string,
    hstyle?: CSSProperties,
}

const HPickItem = React.forwardRef((props: HPickItemProps,ref) => {
	// 对props的结构
    const {
        list,
        hclass,
        hstyle
    } = props
    
    const [move, setMove] = useState(0) // 滚动的距离
    let [itemHeight,setItemHeight] = useState(0) // 单个模块的高度,即每次滚动的距离
    // 对外暴露方法
    const next = () => {
        setMove(pre => pre - itemHeight)
    }
    const prev = () => {
        setMove(pre => pre + itemHeight)
    }
    //用useImperativeHandle暴露一些外部ref能访问的属性
    useImperativeHandle(ref, () => {
        // 需要将暴露的接口返回出去
        return {
            next,
            prev
        };
    })
	
	// 挂载完毕后,获取元素的高度
    useEffect(() => {
        Taro.nextTick(async () => {
            const { height: slidingHeight } = await selectorQueryClientRect('.sliding-container')
            setItemHeight(slidingHeight / list.length)
        })
    }, [])
    return (
        <View className="sliding-container" ref={ref} style={{
            position: 'relative',
            top: `${move}px`,
            transition: "top 0.5s ease-in-out"
        }}>
            {
                list.map(value => <View className={hclass} style={hstyle}>{value}</View>)
            }
        </View>
    )
})
export default HPickItem

父组件

import { View,Text } from "@tarojs/components"
import { useEffect, useRef, useState } from "react"
import HPickItem from "../../components/HPickItem/index"
import "./index.css"

// 创建数据
const createList = (endNumber) => {
    let res : Array<number> = []
    for(let i = endNumber; i > 0; i--){
        res.push(i)
    }
    return res
}
const relaxtion = (props) => {
    // let {relaxtionTime} = props
    let [relaxtionTime,setRelaxtionTime] = useState(15) 
    const controlRef = useRef(null)
    const [pickList,setPickList] = useState(() => createList(15))
    // 开启定时
    useEffect(() => {
        const timer = setInterval(() => {
            if(relaxtionTime === 0){
                clearInterval(timer)
            }
            setRelaxtionTime(pre => pre - 1);
            (controlRef.current as any).next()
        },1000)
    },[])
    return(
        <View className="container">
            {/* 倒计时 */}
            <View className="countdown">
                <HPickItem list={pickList} ref={controlRef}></HPickItem>
            </View>
        </View>
    )
}
/* 倒计时 */
.countdown {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background-color: #F2F2FF;
    box-shadow: 0 0 0 40px #E4E4FF;
    /* 文字 */
    font-size: 38px;
    text-align: center;
    line-height: 80px;
    color: #3F498C;
    /* 定位 */
    float: right;
    margin: 45px 45px 0 0;
    /* 对内容的定位 */
    overflow: hidden;

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值