具有动态背景的div的最大高度和最大宽度?

时间:2019-06-10 12:36:32

标签: javascript css reactjs

我有一个代码,负责裁剪图像并将其裁剪区域保存在div列表中。每个div代表每个裁剪的图像。但是问题是-我不希望它们这么大,我希望它们具有fixed的高度和宽度,例如最多100x100px。

具有有效图像裁剪功能的Codesandbox: https://codesandbox.io/s/fast-frost-0b5tt 与裁剪逻辑相关的代码:

const width = pos.w + "px";
const height = pos.h + "px";
const marginLeft = - pos.x + "px";
const marginTop = - pos.y + "px";

return (
  <div
    key={i}
    style={{
      width: width,
      height: height,
      backgroundSize: "400px 300px",
      backgroundPosition: `top ${marginTop} left ${marginLeft}`,
      backgroundImage: "url('https://boygeniusreport.files.wordpress.com/2016/11/puppy-dog.jpg?quality=98&strip=all&w=400')"
    }}
  />
);

您将看到图像裁剪效果很好,但是新创建的图像具有动态的高度和宽度。

问题:如何使这些新创建的div具有固定的宽度和高度,但又不破坏它?谢谢!

编辑:添加了新链接(旧链接缺少样式)

目标是使子级(裁剪的图像)的高度和宽度保持静态,但将背景图像保持在正确的位置。但是似乎我太笨拙,无法独自完成

4 个答案:

答案 0 :(得分:3)

您的渲染函数中的以下更改将创建一个100px的正方形,其中心位于所选内容的中心点,或者尽可能接近以保持在图像范围内(我不确定如何从此处引用原始图像的宽度和高度)

...
const previews = crops.map(({ pos }, i) => {
  const width = 100 + "px";
  const height = 100 + "px";
  let margx = (pos.w / 2) - 50 + pos.x;
  let margy = (pos.h / 2) - 50 + pos.y;
  if(margx < 0) margx = 0;
  if(margy < 0) margy = 0;
  // this needs origional image width & height (400,300) to get max values
  const maxx = 400-100;
  const maxy = 300-100;
  if(margx > maxx) margx = maxx;
  if(margy > maxy) margy = maxy;
  const marginLeft = - margx + "px";
  const marginTop = - margy + "px";

  return (
    <div
...

答案 1 :(得分:2)

如果同时固定高度和宽度,预览将看起来失真。所以我建议 仅固定高度​​。

  const fixedHeight = 100;
  const zoom = fixedHeight / pos.h;
  const backgroundWidth = 400 * zoom;
  const backgroundHeight = 300 * zoom;
  const width = pos.w * zoom;
  const height = fixedHeight;
  const marginLeft = -pos.x * zoom;
  const marginTop = -pos.y * zoom;

在此codesandbox demo中查看结果。

答案 2 :(得分:1)

我可以在@MunimMunna和@ArleighHix提出的解决方案之间提出一些建议,以改进这两种解决方案。 See result

// setup base image size
const imageBaseWidth = 400;
const imageBaseHeight = 300;
// choose thumbnail size and aspect ratio
const thumbHeight = 100;
const thumbWidth = 200;
// we check which axis needs to be filled to border
const zoomX = thumbWidth / pos.w;
const zoomY = thumbHeight / pos.h;
// you can improve it further by defining max zoom in level so that thumbnails don't show ugly pixels
// just use additional zoom = Math.min(zoom, maxZoom) and some more logic for handling min max margin offset so it wont go outside image bounds
const zoom = Math.max(zoomX, zoomY);
// scaling base image to best fit available space
const backgroundWidth = imageBaseWidth * zoom;
const backgroundHeight = imageBaseHeight * zoom;
// calculate offset to top left corner of biggest rect in selected region that keeps target aspect ratio
const marginLeft = thumbWidth / 2 - (pos.w / 2 + pos.x) * zoom;
const marginTop = thumbHeight / 2 - (pos.h / 2 + pos.y) * zoom;

return (
  <div
    className="preview"
    key={i}
    style={{
      width: thumbWidth + "px",
      height: thumbHeight + "px",
      backgroundSize: `${backgroundWidth}px ${backgroundHeight}px`,
      backgroundPosition: `top ${marginTop}px left ${marginLeft}px`,
      backgroundImage: "url('https://boygeniusreport.files.wordpress.com/2016/11/puppy-dog.jpg?quality=98&strip=all&w=400')"
    }}
  />
);

它在选择区域内选择最大的可能区域,以保持目标缩略图的纵横比,并在需要时对其进行放大。您可以使用fixedHeightfixedWidth

设置目标缩略图的大小

答案 3 :(得分:1)

我会尝试在没有jcrop库的情况下进行重写,以更好地访问所有道具,大小和位置等。 https://stackblitz.com/edit/react-7ubxaa