【React】移动端可视化-如何实现横竖屏切换不重绘Echarts图表

697 阅读1分钟

写在前面:

在移动端查看图标时,经常会有横屏展示的需求,本文实现一个不重绘Echarts图表切换纵向-横向显示的功能

效果如下:

录制_2023_09_07_15_52_06_280.gif

实现原理:

从 BoardInfoContext 中获取 isMobile 变量,使用 useState 定义了一个名为 isHorizontal 的状态变量。然后根据 isMobile 和 isHorizontal 的值,动态计算了 Horizontal 变量,如果满足条件,则为其赋值为 'rotate',否则为空字符串。

在 FullScreenWrap 组件的 CSS 中,定义了一个名为 rotate 的类,通过添加或移除该类来控制旋转效果。

最后,在 TSX 中根据 itemId 的值动态渲染 <FullScreenWrap> 组件,并将 Horizontal 变量应用到 className 属性上。

当点击 <Button> 组件时,会触发 changeHorizontalOrVertical 函数,该函数会根据当前 isHorizontal 的值取反,并更新 isHorizontal 的状态值。

实现步骤:

1. 通过isMobileisHorizontal的值判断是否横屏显示,使用useState记住React组件横屏、竖屏状态

  const { isMobile } = useContext(BoardInfoContext);
  const [isHorizontal, setIsHorizontal] = useState(true);

2. 通过判断条件,在最外层的React组件动态添加&.rotate类,实现横竖屏切换

    const Horizontal = isMobile && isHorizontal ? 'rotate' : '';
    return(
    //需要横屏的最外层React组件
     <FullScreenWrap show={collapsed} className={Horizontal}>
     ...
      </FullScreenWrap>
    )

3.实现&.rotate

  &.rotate {
    top: -100vw;
    transform: rotate(90deg);
    transform-origin: 0% 100%;
    transition: all 0s;
    width: 100vh;
    height: 100vw;
  }

4. 添加控制按钮实现手动切换

const changeHorizontalOrVertical = () => {
    setIsHorizontal(!isHorizontal);
  };
return(
...
 <div className="change-hori-or-vert">
              <Button
                type="primary"
                shape="circle"
                icon={<SyncOutlined />}
                size="large"
                onClick={changeHorizontalOrVertical}
              />
            </div>
          </div>
...
     )

代码如下:

 const { isMobile } = useContext(BoardInfoContext);
  const [isHorizontal, setIsHorizontal] = useState(true);

  const changeHorizontalOrVertical = () => {
    setIsHorizontal(!isHorizontal);
  };
  const Horizontal = isMobile && isHorizontal ? 'rotate' : '';
  return (
    <>
      {itemId && (
        <FullScreenWrap show={collapsed} className={Horizontal}>
        ...
            <div className="change-hori-or-vert">
              <Button
                type="primary"
                shape="circle"
                icon={<SyncOutlined />}
                size="large"
                onClick={changeHorizontalOrVertical}
              />
            </div>
          </div>
        </FullScreenWrap>
      )}
    </>
  );
});

const FullScreenWrap = styled.div<{ show: boolean }>`
...
  &.rotate {
    top: -100vw;
    transform: rotate(90deg);
    transform-origin: 0% 100%;
    transition: all 0s;
    width: 100vh;
    height: 100vw;
  }
`;