基于React的一款自适应组件

这是项目中一款基于react的用于大屏缩放的组件

import React, { Component } from "react";
import styled from "styled-components";

const AdaptBodyBox = styled.div<{
  /** 比例,1为原比例 */
  scale: string;
  /** 高 */
  height: number;
  /** 宽 */
  width: number;
  /** 等比缩放 */
  equalProportion: boolean;
}>`
  height: 100%;
  width: 100%;
  overflow: auto;
  position: relative;
  &::-webkit-scrollbar {
    display: none;
  }
  .adapt-border {
    position: absolute;
    left: ${(props) => (props.equalProportion ? "50%" : 0)};
    top: 0;
    transform-origin: ${(props) => (props.equalProportion ? "top center" : "top left")};
    height: ${(props) => props.height}px;
    width: ${(props) => props.width}px;
    transform: ${(props) => (props.equalProportion ? `translateX(-50%) scale(${props.scale})` : `scale(${props.scale})`)};
    /* transition: transform 1s ease-out; */
  }
`;
interface Props {
  /** 开启自适应,宽高有变形的情况 */
  adaptive: boolean;
  /** 等比例缩放 */
  equalProportion: boolean;
  /** 设计的宽度 */
  designWidth: number;
  /** 设计高度 */
  designHeight: number;
  /** 传入子元素 */
  children: React.ReactNode;
}
interface State {
  /** 缩放比例 */
  scale: string;
}

/**
 * 适应固定比例缩放组件,使用父元素设置宽高,可自适应 adaptive属性优先与 equalProportion
 * @author
 * @date 
 * @export
 * @class AdaptBody
 * @extends {Component<Props, State>}
 */
export class AdaptBody extends Component<Props, State> {
  static defaultProps = {
    adaptive: true,
    equalProportion: false,
    designWidth: 1920,
    designHeight: 1080,
  };
  state: State = {
    scale: "1",
  };
  componentDidMount() {
    this.onResize();
    window.addEventListener("resize", this.onResize);
  }
  componentWillUnmount() {
    window.removeEventListener("resize", this.onResize);
  }

  render() {
    const { scale } = this.state;
    const { designWidth, designHeight, equalProportion } = this.props;
    return (
      <AdaptBodyBox scale={scale} height={designHeight} width={designWidth} equalProportion={equalProportion} id="adapt_body_box">
        <div className="adapt-border">{this.props.children}</div>
      </AdaptBodyBox>
    );
  }
  /** 调整尺寸事件 */
  onResize = () => {
    const { adaptive, designWidth, designHeight, equalProportion } = this.props;
    const domBox = document.getElementById("adapt_body_box") as HTMLElement;
    const realWidth = domBox.offsetWidth || window.document.body.clientWidth;
    const realHeight = domBox.offsetHeight || window.document.body.clientHeight;
    const getDesignWidth = designWidth;
    const getDesignHeight = designHeight;
    if (adaptive) {
      this.setState({ scale: `${realWidth / getDesignWidth}, ${realHeight / getDesignHeight}` });
    } else if (equalProportion) {
      const designSreenRatio = designWidth / designHeight;
      const realScreenRatio = realWidth / realHeight;
      if (realScreenRatio > designSreenRatio) {
        // 实际画面更宽
        this.setState({ scale: `${realHeight / designHeight}` });
      } else {
        // 实际画面更窄
        this.setState({ scale: `${realWidth / designWidth}` });
      }
    } else {
      this.setState({ scale: "1" });
    }
  };
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值