react 横向文字滚动动画 ,及纵向文字滚动动画带有间歇时间 交替渐变显示文字动画

发布时间 2024-01-11 11:17:30作者: 卢老师不想编程

水平滚动

demo.less
#scroll_x {
  width: 300px;
  height: 30px;
  background-color: #ccc;
  color: green;
  position: relative;
  overflow: hidden;
}
#scroll_x_text {
  font-size: 20px;
  position: absolute;
  white-space: nowrap;
  word-wrap: normal;
  top: 0;
}
 
demo.tsx
import React, { useEffect, useState } from "react"
import './demo.less'
const Demo = () => {
    const [left, setLeft] = useState(9999)
    const [transform, setTransform] = useState(0)
    const [transition, setTransition] = useState(`transform 5s linear`)
    const [stopInterval, setStopInterval] = useState(false)
    let scrollXStyle = {
        left,
        transform: `translateX(${transform}px)`,
        transition
    }
    let timerX
    const text = 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrtttttttttttttttttttttttyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
    const setPosition = () => {
        const textWidth = document.getElementById('scroll_x_text')?.clientWidth
        const fatherWidth = document.getElementById('scroll_x')?.clientWidth
        setStopInterval(true)
        if (fatherWidth && textWidth) {
            setLeft(fatherWidth)
            if (transform < 0 && ((Math.abs(transform) - fatherWidth) > textWidth)) {
                setTransition('')
                setTransform(0)
                setTimeout(() => {
                    setStopInterval(false)
                }, 100)

            } else {
                setTransition(`transform 5s linear`)
                setTransform(transform - fatherWidth)
                setTimeout(() => {
                    setStopInterval(false)
                }, 5000)
            }
        }
    }
    useEffect(() => {
        if (stopInterval) {
            clearInterval('timerX')
        } else {
            timerX = setInterval(setPosition, 1000)
        }
        return () => {
            clearInterval(timerX)
        }
    }, [stopInterval])
    return <div id="scroll_x">
        <div id="scroll_x_text" style={scrollXStyle}>
            {text}
        </div>
    </div>
}
export default Demo
 
 
纵向滚动
demo1.less
#scroll_y {
  width: 300px;
  height: 60px;
  background-color: #ccc;
  color: green;
  position: relative;
  top: 0px;
  left: 300px;
  overflow: hidden;
}
#scroll_y_text {
  position: absolute;
  word-wrap: break-word;
  top: 50px;
  left: 0;
  font-size: 20px;
  line-height: 30px;
  color: green;
}
 
demo.tsx
import React, { useEffect, useState } from "react"
import './demo1.less'
const Demo = () => {
    const [top, setTop] = useState(9999)
    const [width, setWidth] = useState(9999)
    const [transform, setTransform] = useState(0)
    const [transition, setTransition] = useState('transform 5s linear')
    const [stopInterval, setStopInterval] = useState(false)
    let scrollYStyle = {
        width,
        top,
        transform: `translateY(${transform}px)`,
        transition
    }
    let timerY
    const text = 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrtttttttttttttttttttttttyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
    const setPosition = () => {
        const fatherWidth = document.getElementById('scroll_y')?.clientWidth
        const textHeight = document.getElementById('scroll_y_text')?.clientHeight
        const fatherHeight = document.getElementById('scroll_y')?.clientHeight
        fatherWidth && setWidth(fatherWidth)
        setStopInterval(true)
        if (fatherHeight && textHeight) {
            setTop(fatherHeight)
            if (transform < 0 && ((Math.abs(transform) - fatherHeight) > textHeight)) {
                setTransition('')
                setTransform(0)
                setTimeout(() => {
                    setStopInterval(false)
                }, 100)

            } else {
                setTransition('transform 5s linear')
                setTransform(transform - fatherHeight)
                setTimeout(() => {
                    setStopInterval(false)
                }, 5000)
            }
        }


    }
    useEffect(() => {
        if (stopInterval) {
            clearInterval('timerY')
        } else {
            timerY = setInterval(setPosition, 1000)
        }
        return () => {
            clearInterval(timerY)
        }
    }, [stopInterval])
    return <div id="scroll_y">
        <div id="scroll_y_text" style={scrollYStyle}>
            {text}
        </div>
    </div>
}
export default Demo
 
文字渐变交替显示
demo3.less
#gradient_father {
  width: 300px;
  height: 60px;
  font-size: 12px;
  background-color: #ccc;
  color: green;
  position: relative;
  top: 200px;
  left: 300px;
  overflow: hidden;
}
#gradient_text_top {
  position: absolute;
  word-wrap: break-word;
  top: 50px;
  left: 0;
  font-size: 20px;
  line-height: 30px;
}
#gradient_text_bottom {
  position: absolute;
  word-wrap: break-word;
  top: 50px;
  left: 0;
  font-size: 20px;
  line-height: 30px;
}
 
demo.tsx
 
import React, { useEffect, useState } from "react"
import './demo3.less'
const Demo = () => {
    const [isFirst, setIsFirst] = useState(true)
    const [opacityFirst, setOpacityFirst] = useState(1)
    const [opacitySecond, setOpacitySecond] = useState(0)
    const [topFirst, setTopFirst] = useState(200)
    const [topSecond, setTopSecond] = useState(200)
    const [width, setWidth] = useState(0)
    const [transformFirst, setTransformFirst] = useState(0)
    const [transformSecond, setTransformSecond] = useState(0)
    const [transition, setTransition] = useState('opacity 3s linear')
    const [stopInterval, setStopInterval] = useState(false)
    let gradientTStyle = {
        width,
        top: topFirst,
        transform: `translateY(${transformFirst}px)`,
        transition,
        opacity: opacityFirst
    }
    let gradientBStyle = {
        width,
        top: topSecond,
        transform: `translateY(${transformSecond}px)`,
        transition,
        opacity: opacitySecond
    }
    let gradientTimer
    const text = 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrtttttttttttttttttttttttyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
    const setPosition = () => {
        const fatherWidth = document.getElementById('gradient_father')?.clientWidth
        const textHeight = document.getElementById('gradient_text_top')?.clientHeight || document.getElementById('gradient_text_bottom')?.clientHeight
        const fatherHeight = document.getElementById('gradient_father')?.clientHeight
        fatherWidth && setWidth(fatherWidth)
        setStopInterval(true)
        if (fatherHeight && textHeight) {
            if (isFirst) {
                setTopFirst(fatherHeight + fatherHeight)
                setTopSecond(fatherHeight + fatherHeight)
            }
            if (transformFirst < 0 && (Math.abs(transformFirst) > textHeight)) {
                setTransition('')
                setTransformFirst(0)
                setTransformSecond(0)
                setIsFirst(true)
                setTimeout(() => {
                    setStopInterval(false)
                }, 100)

            } else {
                setTransition('opacity 3s linear')
                if (isFirst) {
                    setTransformFirst(transformFirst - fatherHeight)
                    setIsFirst(false)
                }
                if (opacitySecond === 0) {
                    setTransformSecond(transformSecond - fatherHeight - fatherHeight)
                }
                if (opacityFirst === 0) {
                    setTransformFirst(transformFirst - fatherHeight - fatherHeight)
                }
                setOpacityFirst(opacityFirst === 0 ? 1 : 0)
                setOpacitySecond(opacitySecond === 0 ? 1 : 0)
                setTimeout(() => {
                    setStopInterval(false)
                }, 3000)
            }
        }


    }
    useEffect(() => {
        if (stopInterval) {
            clearInterval('gradientTimer')
        } else {
            gradientTimer = setInterval(setPosition, 2000)
        }
        return () => {
            clearInterval(gradientTimer)
        }
    }, [stopInterval])
    return <div id="gradient_father">
        <div id="gradient_text_top" style={gradientTStyle}>
            {text}
        </div>
        <div id="gradient_text_bottom" style={gradientBStyle}>
            {text}
        </div>
    </div>
}
export default Demo