我目前正在Reaction中构建某种表情包编辑器,为此,我使用konvajs来实现类似于画布的功能. 我的问题是我无法将Canvastage中的项目居中,因为似乎有一些属性刚刚覆盖了我的样式. 这是我的Reaction-Component中的返回语句的一部分:

<div className="mycanvas">
    <Stage width={500} height={500} className="stage">
        <Layer>
            <Image image={image} className="meme" />
            {textFields.map((text) => (
                <Text
                    text={text}
                    draggable
                    fontFamily="Impact"
                    fontSize="30"
                    stroke="white"
                />
            ))}
        </Layer>
    </Stage>
</div>

这就是输出的呈现方式.

current rendering output

我已经把包装的背景涂成了蓝色,以显示图像应该在哪个框中居中.

我已经在类"MyCanvas"、"Stage"和"Meme"以及"konvajs-Content"上try 了CSS(因为某些原因,这在我的判断器中显示了出来).我已经使用了Align-Items:Center、March:Auto和其他几个选项,但我认为普通的css在这里并不适用. 我认为这是一个关于konvajs组件的通用样式的问题,但不幸的是,我找不到任何关于stackoverflow或konva文档的解决方案.

推荐答案

这是一个css帮不上忙的例子.当使用您提供的xy坐标的高度和宽度将图像应用到画布时,图像的像素将成为栅格化画布的一部分.换句话说,图像并不是独立于画布而存在的.

因此,如果您想要将图像放在画布内部居中,则需要做一些数学运算来计算将图像放置在画布内部居中的xy坐标.

演示

例如,如果画布大小为500px高,而图像的高度为350px,则需要将y位置设置为75px(即(500 - 350) / 2).

下面的演示代码展示了如何复制CSSobject-fit: contain的行为.这将调整图像以在一个方向上填充画布,然后在另一个方向上使图像居中.

import { useState, useEffect } from "react";
import { Stage, Layer, Image, Text } from "react-konva";

function Example() {
  const w = window.innerWidth;
  const h = window.innerHeight;
  const src = "https://konvajs.org/assets/yoda.jpg";

  const [image, setImage] = useState(null);
  const [pos, setPos] = useState({ x: 0, y: 0 });

  useEffect(() => {
    const image = new window.Image();
    image.src = src;
    image.addEventListener("load", handleLoad);

    function handleLoad(event) {
      const image = event.currentTarget;
      /* after the image is loaded, you can get it's dimensions */
      const imgNaturalWidth = image.width;
      const imgNaturalHeight = image.height;

      /* 
        calculate the horizontal and vertical ratio of the 
        image dimensions versus the canvas dimensions
      */
      const hRatio = w / imgNaturalWidth;
      const vRatio = h / imgNaturalHeight;

      /*
        to replicate the CSS Object-Fit "contain" behavior,
        choose the smaller of the horizontal and vertical 
        ratios

        if you want a "cover" behavior, use Math.max to 
        choose the larger of the two ratios instead
      */
      const ratio = Math.min(hRatio, vRatio);
      /* 
        scale the image to fit the canvas 
      */
      image.width = imgNaturalWidth * ratio;
      image.height = imgNaturalHeight * ratio;

      /* 
        calculate the offsets so the image is centered inside
        the canvas
      */
      const xOffset = (w - image.width) / 2;
      const yOffset = (h - image.height) / 2;

      setPos({
        x: xOffset,
        y: yOffset
      });
      setImage(image);
    }

    return () => {
      image.removeEventListener("load", handleLoad);
    };
  }, [src, h, w]);

  return (
    <Stage width={w} height={h} style={{ background: "black" }}>
      <Layer>
        <Image x={pos.x} y={pos.y} image={image} />
        <Text
          text="I am centered"
          fontFamily="Impact"
          fontSize={50}
          stroke="white"
          strokeWidth={1}
          x={pos.x}
          y={pos.y}
        />
      </Layer>
    </Stage>
  );
}

Css相关问答推荐

Tailwind CSS group-hover不适用于自定义前置码

如何在JavaFX中设置分隔符的样式?

如何使用CSS滚动驱动动画重复时间轴范围

位置:固定元素只是不固定

将鼠标悬停在具有效果的元素上

如何使背景出现在具有自己背景 colored颜色 的子元素上

:not() 适用于特定类中的所有 html 标签

混合网格自动布局与固定的行列位置

有没有办法在 CSS 字体速记中使用数字字体粗细?

更改 20 个实例中的一个组件的样式

调整屏幕大小时无法让我的视频背景保持不变

在所有移动设备中禁用滚动

ID 在整个页面中必须是唯一的吗?

如何保持标题静态,滚动时始终位于顶部?

Chrome 呈现 colored颜色 的方式与 Safari 和 Firefox 不同

Sass 无效的 CSS 错误:预期的表达式

在移动网络上禁用捏zoom

css 中的 clearfix 类有什么作用?

将 webkit 滚动条样式应用于指定元素

CSS背景图像不透明度?