消息列表无缝滚动(跑马灯)

211 阅读1分钟

消息列表,使用css3 animation 动画,实现跑马灯效果。 perspective: 1000; 解决文字抖动问题。

// index.tsx (封装ReactScroll) 

import React, { useEffect, useState } from "react";
import "./index.less";

const ReactScroll = (props) => {
  const [actived, setActived] = useState(true);
  const [rerender, setRerender] = useState(false);
  const [length, setLength] = useState(0);

  useEffect(() => {
    const scrollBox = document.querySelector(".scrollBox");
    const boxHeight = scrollBox?.offsetHeight;
    const childsLength = scrollBox.childNodes.length;
    const containerHeight =
      document.querySelector(".scrollContainer")?.offsetHeight;
    setLength(childsLength);
    if (boxHeight < containerHeight) {
      setRerender(false);
    } else {
      setRerender(true);
    }
  }, [props.children]);

  const renderContent = () => {
    return (
      <div
        style={{
          animation: `rowUp ${length ?? 15}s linear infinite`,
        }}
        className={`scrollBox ${actived && rerender ? "active" : "paused"}`}
        onMouseEnter={() => {
          setActived(false);
        }}
        onMouseLeave={() => {
          setActived(true);
        }}
      >
        {props.children}
      </div>
    );
  };
  return (
    <div className="scrollContainer" {...props}>
      {renderContent()}
      {rerender && renderContent()}
    </div>
  );
};

export default ReactScroll;



// index.less
@keyframes rowUp {
  0% {
    transform: translateY(0);
    // backface-visibility: hidden;
    // -webkit-backface-visibility: hidden;
    perspective: 1000; // 解决文字抖动问题。
    -webkit-perspective: 1000;
    -moz-perspective: 1000;
    -ms-perspective: 1000;
  }
  100% {
    transform: translateY(-100%);
    // backface-visibility: hidden;
    // -webkit-backface-visibility: hidden;
    perspective: 1000;
    -webkit-perspective: 1000;
    -moz-perspective: 1000;
    -ms-perspective: 1000;
  }
}

.active {
  animation-play-state: running !important;
}

.paused {
  animation-play-state: paused !important;
}

// 使用
import { Empty } from 'antd';
import React from 'react';
import ReactScroll from '@/components/ReactScroll';

const res = [
  {
    comment: 'starting',
  },
  {
    comment: '锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦。',
  },
  {
    comment: '锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦。',
  },
  {
    comment: '锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦。',
  },
  {
    comment: '锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦。',
  },
  {
    comment: '锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦。',
  },
  {
    comment: '锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦。',
  },
  {
    comment: '锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦。',
  },
  {
    comment: 'ending',
  },
];

const ScrollList = () => {
  return (
    <div
      style={{
        borderRadius: 4,
        boxShadow: '8px #f1f1f1',
        border: '4px solid #f5f5f5',
      }}
    >
      {res?.length ? (
        <ReactScroll style={{ width: '100%', height: 300, overflow: 'hidden' }}>
          {res?.map((item, index) => (
            <div key={index}>{item?.comment}</div>
          ))}
        </ReactScroll>
      ) : (
        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
      )}
    </div>
  );
};

export default ScrollList;