981377660LMT / ts

ts学习
6 stars 1 forks source link

object-fit #472

Open 981377660LMT opened 9 months ago

981377660LMT commented 9 months ago

object-fit 属性通常用于 <img><video> 标签,用于控制这些元素的内容如何适应其容器的大小。以下是一些使用示例:

  1. object-fit: fill;
<img src="image.jpg" style="width: 300px; height: 200px; object-fit: fill;">

此设置会拉伸图片以填充容器,可能会改变图片的宽高比。

  1. object-fit: contain;
<img src="image.jpg" style="width: 300px; height: 200px; object-fit: contain;">

此设置会保持图片的宽高比不变,同时尽可能地填充容器。如果容器的宽高比与图片的不同,可能会在容器中留下空白区域。

  1. object-fit: cover;
<img src="image.jpg" style="width: 300px; height: 200px; object-fit: cover;">

此设置会保持图片的宽高比不变,同时尽可能地覆盖容器。如果容器的宽高比与图片的不同,可能会剪切掉图片的一部分。

  1. object-fit: none;
<img src="image.jpg" style="width: 300px; height: 200px; object-fit: none;">

此设置会保持图片的原始大小,忽略容器的大小。

  1. object-fit: scale-down;
<img src="image.jpg" style="width: 300px; height: 200px; object-fit: scale-down;">

此设置会将图片的尺寸与 nonecontain 中较小的一个相同,也就是说,图片会尽可能地大,但是不会超过容器的大小,也不会超过图片的原始大小。

981377660LMT commented 9 months ago

代码实现

  1. cover 按照长边缩放,并且图片与容器中心对准;

/**

/**

981377660LMT commented 9 months ago

zrender 中使用

private _createFileItem (): Image {
    const { file, style = {} } = this.props;
    const containerWidth = style.width ?? 30;
    const containerHeight = style.height ?? 30;
    const { newWidth: fileWidth, newHeight: fileHeight } = scaleImageByBiggerRatio(
      file.width ?? containerWidth,
      file.height ?? containerHeight,
      containerWidth,
      containerHeight
    );
    const { translateX, translateY } = calculateCenterAlignedImageTranslation(fileWidth, fileHeight, containerWidth, containerHeight);

    const fileProps: ImageProps = {
      key: FileItem._fileKey,
      name: file.name,
      style: {
        image: getImageByFile(file),
        width: fileWidth,
        height: fileHeight,
        x: translateX,
        y: translateY
      },
      z: style.z,
      cursor: style.cursor,
      clipPath: new Rect({
        shape: {
          width: containerWidth,
          height: containerHeight,
          r: style.borderRadius ?? 0
        },
        z: style.z,
        silent: true
      }),
      onload: (imageLike) => {
        // 图片加载失败时,显示默认图片
        if (imageLike.height === 0) {
          if ('src' in imageLike) {
            imageLike.src = FILE_TYPE_ICON[FILE_TYPE.IMG];
          }
        }
        // !图片load完后需要重新刷新整个组件,避免border被图片clip
        this.render();
      }
    };

    let fileItem = this.getReuseElement(FileItem._fileKey) as Image | undefined;
    if (fileItem) {
      fileItem.attr(fileProps);
    } else {
      fileItem = new Image(fileProps);

      this._addHandler(fileItem, 'mouseover', (e) => {
        this.props.onMouseEnter?.(e, this, fileItem!);
      });
      this._addHandler(fileItem, 'mouseout', (e) => {
        this.props.onMouseLeave?.(e, this, fileItem!);
      });
      this._addHandler(fileItem, 'click', (e) => {
        this.props.onClick?.(e, this, fileItem!);
      });
    }

    return fileItem;
  }