根据外框宽高,font-size自适应大小 2021-12-07

目标

根据外框宽高,font-size自适应大小

效果图

效果图

npm地址

传送门

源码

autoSizeSpan.vue

<template>
  <div class="auto-size-span-box" :style="boxStyle" ref="box">
    <div class="auto-size-span" ref="text" :style="textStyle">
      {{ text }}
    </div>
  </div>
</template>

<script>
// 未设定宽高则外框根据内容撑开
// scale-down: 未设定font-size设定了宽高,能放下则居中显示,放不下则缩小居中显示,小了保持大小居中
// contain: font-size实际意义不大,相当于缩放的基础值,设定了宽高,小了拉大,大了缩小
export default {
  name: 'autoSizeSpan',
  props: {
    text: {
      default: ""
    },
    objectFit: {
      default: "scale-down",
      validator: function(value) {
        // 这个值必须匹配下列字符串中的一个
        return ["scale-down", "contain"].indexOf(value) !== -1;
      }
    }
  },
  data() {
    return {
      defTextStyle: {
        scale: 1,
        lineHeight: "1.5"
      },
      textStyle_: {},
      boxStyle: {
        width: undefined,
        height: undefined
      }
    };
  },
  computed: {
    textStyle() {
      let textStyle = { ...this.textStyle_ };
      let scale = textStyle.scale;
      delete textStyle.scale;
      textStyle.transform = `scale(${scale}) translate(-50%, -50%)`;
      return textStyle;
    }
  },
  mounted() {
    this.defTextStyle.lineHeight = getComputedStyle(this.$refs.text)["line-height"];
    this.calculate();
  },
  methods: {
    calculate() {
      let box = this.$refs.box,
        text = this.$refs.text;
      this.textStyle_ = { ...this.defTextStyle };
      this.$nextTick(() => {
        let bw = box.offsetWidth,
          bh = box.offsetHeight,
          tw = text.offsetWidth,
          th = text.offsetHeight;

        // 未设定宽高时的处理
        if (bw == 0) {
          bw = tw;
          this.boxStyle.width = `${bw}px`;
        }
        if (bh == 0) {
          bh = th;
          this.boxStyle.height = `${bh}px`;
        }

        // 根据传入的策略,获得目标宽高
        let to = this[this.objectFit]({
          w: bw,
          h: bh,
          ow: tw,
          oh: th
        });

        // 设定缩放比例
        let scale = to.w / tw;
        this.textStyle_ = {
          scale: scale,
          // 行高很烦人,干脆直接放弃处理了,脑子都不转了
          lineHeight: `0px`
        };
      });
    },
    /**
     * 宽高自适应计算方案 scale-down
     * 版权声明:本文为CSDN博主「anywo01」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
     * 原文链接:https://blog.csdn.net/y1377593732/article/details/115502163
     */
    "scale-down": parms => {
      var whTmp = parms.w / parms.h;
      var owhTmp = parms.ow / parms.oh;
      var toW, toH;
      if (whTmp > owhTmp && parms.h < parms.oh) {
        toW = parseInt(owhTmp * parms.h);
        toH = parms.h;
      } else if (whTmp <= owhTmp && parms.w < parms.ow) {
        toW = parms.w;
        toH = parseInt(parms.w / owhTmp);
      } else {
        toW = parms.ow;
        toH = parms.oh;
      }
      return {
        w: toW,
        h: toH
      };
    },
    /**
     * 宽高自适应计算方案 contain
     * 版权声明:本文为CSDN博主「anywo01」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
     * 原文链接:https://blog.csdn.net/y1377593732/article/details/121733525
     */
    contain(parms) {
      var whTmp = parms.w / parms.h;
      var owhTmp = parms.ow / parms.oh;
      var toW, toH;
      if (whTmp > owhTmp) {
        toW = parseInt(owhTmp * parms.h);
        toH = parms.h;
      } else if (whTmp <= owhTmp) {
        toW = parms.w;
        toH = parseInt(parms.w / owhTmp);
      }
      return {
        w: toW,
        h: toH
      };
    }
  },
  updated() {},
  watch: {
    text: {
      handler() {
        this.calculate();
      }
    }
  }
};
</script>

<style scoped>
.auto-size-span-box {
  position: relative;
  display: inline-block;
  vertical-align: bottom;
}
.auto-size-span {
  display: inline-block;
  transform-origin: left center;
  position: absolute;
  top: 50%;
  left: 50%;
  white-space: nowrap;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值