• 跑马灯 封装


    为什么要自己写组件
    html中的标签可实现文字跑马灯效果,但这个标签在H5标准中已经被废弃,未来可能不受支持。
    自定义的组件调整动画效果、性能方面更灵活,可以实现更多需求。
    组件说明
    本组件是基于React+hooks开发的,也可以改成vue的,动画原理一样。
    组件可实现模拟标签的效果,也可使用css3动画获得更流畅的体验
    参数说明:
    v - 速度,每秒移动多少个像素,默认100
    t - 刷新一次的时长(ms),默认50,只在frameWise为true时有效
    frameWise - 为true即表示使用逐帧动画效果,内容运动过程中有振动的感觉;
    为false则使用css3的过渡效果制作成动画,性能好,比较较流畅
    使用举例
    1. 模拟逐帧动画
    <CssMarquee v={80}>{
    list.map(item =>
    <div className={'item'} onClick={() => gotoDetail(item)}>
    <span className={'point'}>·</span>{item.content}
    </div>
    )}
    </CssMarquee>
    1
    2
    3
    4
    5
    6
    7
    2. css3动画
    <CssMarquee frameWise v={80} t={36}>{
    list.map(item =>
    <div className={'item'} onClick={() => gotoDetail(item)}>
    <span className={'point'}>·</span>{item.content}
    </div>
    )}
    </CssMarquee>
    1
    2
    3
    4
    5
    6
    7
    组件源码
    import { useState, useEffect, useRef } from 'react'

    // children - 传入的内容,即调用组件时写在首位标签之间的内容
    // v - 每秒移动多少个像素
    // t - 刷新一次的时长(ms),只在frameWise为true时有效
    // frameWise - 为true即表示使用逐帧动画效果,内容运动过程中有振动的感觉;
    // 为false则使用css3的过渡效果制作成动画,性能好,比较较流畅
    export default ({ children, frameWise, v = 100, t = 50 }) => {
    const wrapRef = useRef() // 动画容器
    const contentRef = useRef() // 动画内容
    const [offsetX, setOffsetX] = useState(0)
    const _offsetX = useRef()

    useEffect(() => {
    frameWise && (_offsetX.current = offsetX)
    })
    useEffect(() => {
    const wrapWidth = wrapRef.current.offsetWidth // 容器宽度
    const contentWidth = contentRef.current.scrollWidth // 内容宽度

    if (frameWise) {
    // 使用定时器来控制移动
    setOffsetX(wrapWidth)
    const timer = setInterval(() => {
    if (-_offsetX.current > contentWidth) {
    setOffsetX(wrapWidth)
    } else {
    setOffsetX(x => x - v * (t / 1000))
    }
    }, t)
    return () => {
    clearInterval(timer)
    }
    }

    // 使用css3的过渡实现
    const deltaX = contentWidth + wrapWidth // 移动距离
    const deltaT = deltaX / v + 's' // 周期
    contentRef.current.style.transitionTimingFunction = 'linear' // 线性动画

    const animation = () => {
    // 每个周期的开始,先让内容归位
    contentRef.current.style['transition-duration'] = '0s'
    contentRef.current.style.transform = `translateX(${wrapWidth}px)`
    // 设置过渡时间和目标
    setTimeout(() => {
    contentRef.current.style.transitionDuration = deltaT
    contentRef.current.style.transform = `translateX(${-contentWidth}px)`
    }, 100)
    }
    animation()

    const timer = setInterval(() => {
    animation()
    }, deltaX * 1000 / v + 100)

    return () => {
    clearInterval(timer)
    }
    }, [])

    return (children.length
    ? <div className={'m-cssMarquee'}>
    <div className={'wrap'} ref={wrapRef}>{
    frameWise
    ? <div className={'content'} ref={contentRef} style={{ transform: `translateX(${offsetX}px)` }}>{children}</div>
    : <div className={'content'} ref={contentRef}>{children}</div>
    }
    </div>
    </div>
    : null
    )
    }
    ————————————————
    版权声明:本文为CSDN博主「daoke_li」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/daoke_li/article/details/117300799

  • 相关阅读:
    [React] Improve developer experience for accessing context with a custom React hook
    [CSS] Create a self-centering, full-width stripe with CSS Grid
    android之使用mvn构建创造项目步骤
    Android读取Excel文件
    Android之RAS加密算法测试
    android 内存溢出oom错误的一些小见解
    Android之在应用程序内部关注某人的微信
    Android之使用picker打开相应的app
    MAC之查看日历
    MAC之tar解压与压缩打包命令
  • 原文地址:https://www.cnblogs.com/wsj1/p/16189184.html
Copyright © 2020-2023  润新知