先看效果:左侧是原生的object-fit: cover + img
右侧是canvas 处理之后的 模仿object-fit: cover 的效果,src 是转换之后的base64 地址
可以结合style样式发现右图并没有object-fit: cover,但是效果与左同。

直接贴代码吧
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #img {
      width: 200px;
      height: 500px;
      display: inline-block;
      object-fit: cover;
    }
    .box {
      display: flex;
    }
    #img1 {
      width: 200px;
      height: 100%;
      margin-left: 10px;
    }
    #canvas {
      display: none;
    }
  </style>
</head>
<body>
  <div class="box">
    <img src="./img/chun.jpg" id="img" alt="" srcset="">
    <img src="" id="img1" alt="" srcset="">
  </div>
  <canvas id="canvas" width="1000px" height="500px"></canvas>
  <button>
    保存
  </button>
  <script>
    cropImg({
      proportion: 0.4
    }).then((url) => {
      document.getElementById('img1').src = url
    })
    /**
     *  宽度与高度 比例
     *  计算方式 宽度/高度
     *  @param {Number} proportion
     */
    function cropImg ({
      proportion,
    }) {
      const canvas = document.getElementById('canvas')
      const ctx = canvas.getContext('2d')
      var image = new Image()
      image.src =
        './img/chun.jpg'
      return new Promise((resolve, reject) => {
        image.onload = function () {
          console.log('设置比例、图片比例', proportion, '----', image.width / image.height)
          let orgProportion = image.width / image.height
          /* image - 我们想要裁剪并显示在浏览器上的图像本身。
              sx(源图像 x 轴)- 此参数表示你要从 x 轴剪切或开始裁剪图像的位置。
              sy(源图像 y 轴)- 此参数表示你要从 y 轴剪切或开始裁剪图像的位置。
              sWidth - 从 sx 开始的图像宽度。
              sHeight - 从 sy 开始的图像高度。
              dx - 从 x 轴开始在屏幕上绘制图像的点。
              dy - 从 y 轴开始在屏幕上绘制图像的点。
              dWidth - 应该在屏幕上显示的图像的长度。
              dHeight - 应显示在屏幕上的图像高度。 */
          let ctxwidth = 0
          let ctxheight = 0
          let x = 0
          let y = 0
          let w = image.width
          let h = image.height
          let width = w
          let height = h
          if (proportion) {
            if (orgProportion <= proportion) {
              if (w > h) {
                width = h / proportion
              } else {
                height = w / proportion
              }
            } else {
              // 比例不足需要 同时裁剪宽高
              if (w > h) {
                height = w * proportion
              } else {
                width = h * proportion
              }
            }
          }
          if (orgProportion <= proportion) {
            if (w > h) {
              x = (w - width) / 2
            }
            if (h > w) {
              y = (h - height) / 2
            }
          } else {
            console.log('比例不足')
            if (w > h) {
              y = (h - height) / 2
            } else {
              x = (w - width) / 2
            }
          }
          // console.log(x, y, width, height, image.width, image.height)
          ctxwidth = width
          ctxheight = height
          canvas.width = ctxwidth
          canvas.height = ctxheight
          ctx.drawImage(image, x, y, width, height, 0, 0, width, height)
          let dataURL = canvas.toDataURL('image/png', 1.0)
          resolve(dataURL)
        }
        image.onerror = function (err) {
          reject(err)
        }
      })
    }
  
  </script>
</body>
</html>


















