react 文字跑马灯

之前的一个 pc 端项目,有文字滚动的功能,找了下,没有合适的轮子,于是自己造了一个

目前只支持横向滚动

index.tsx
import React, { useRef, useEffect, useState } from 'react'
import './index.css'
import styled from 'styled-components'

interface TextScrollProps {
  /**
   * 内容
   */
  content: string
  /**
   * 持续时间/s
   */
  duration: number
}

function TextScroll(props: TextScrollProps) {
  const { content, duration } = props

  const defaultState = {
    contentWidth: 0,
    left: 0,
    duration,
  }

  const [state, setState] = useState(defaultState)

  let ref = useRef<HTMLParagraphElement>(null)

  useEffect(() => {
    const { offsetWidth, parentElement } = ref.current as HTMLParagraphElement

    setState({
      ...state,
      contentWidth: offsetWidth,
      left: parentElement!.offsetWidth,
    })
  }, [])

  const { contentWidth, left, duration: timing } = state

  const animationName = `marquee_${contentWidth}`

  const Text = styled.p`
    position: relative;
    left: ${left}px;
    animation: ${animationName} ${timing}s linear infinite both;
    animation-play-state: running;
    animation-fill-mode: forwards;

    @keyframes ${animationName} {
      0% {
        transform: translateX(0px);
      }

      100% {
        transform: translateX(-${contentWidth + left}px);
      }
    }
  `

  return (
    <div className="marquee_box">
      <Text ref={ref}>{content}</Text>
    </div>
  )
}
TextScroll.defaultProps = {
  content: '',
  duration: 3,
}

export default React.memo(TextScroll)
index.css
.marquee_box {
  width: 100%;
  height: 100%;
  overflow: hidden;
  word-break: keep-all;
  white-space: nowrap;
  display: flex;
  align-items: center;
}

.marquee_box p {
  display: inline-block;
}

.marquee_box:hover p {
  animation-play-state: paused;
  cursor: default;
}

有更好实现思路的童鞋可以来给我上一课[让我看看]

预览地址

点我

更多实用组件:https://github.com/isxiaoxin/front_end_wheel

你可能感兴趣的:(造轮子,typescript,reactjs,css3,javascript,es6)