css - 如何将 konvajs 中的元素居中?

标签 css reactjs konvajs

我目前正在 React 中构建某种模因编辑器,为此我使用 konvajs 来实现类似于 Canvas 的功能。 我的问题是我无法将 Canvas 舞台内的元素居中,因为似乎有一些属性只是覆盖了我的样式。 这是我的 react 组件中返回语句的(一部分):

<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”(由于某种原因出现在我的检查器中)上尝试过CSS。我使用过align-items: center、margin: auto 和其他一些,但我认为普通的CSS 在这里并不适用。 我认为这是关于 konvajs 组件的一般样式的问题,但不幸的是我在 stackoverflow 或 konva 文档上找不到任何解决方案。

最佳答案

这是 CSS 无法提供帮助的情况。当使用您提供的 xy 坐标处的高度和宽度将图像应用到 Canvas 时,图像的像素将成为光栅化 Canvas 的一部分。换句话说,图像并不独立于 Canvas 而存在。

因此,如果您想让图像在 Canvas 内居中,您需要做一些数学计算来计算放置图像的 xy 坐标位于 Canvas 中央。

Demo

例如,如果您的 Canvas 尺寸为 500 像素高,图像高度为 350 像素,那么您需要将 y 位置设置为 75px(即 (500 - 350)/2)。

下面的演示代码展示了如何复制 CSS object-fit: contains 的行为。这将调整图像以在一个方向上填充 Canvas ,然后将图像在另一个方向上居中。

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 - 如何将 konvajs 中的元素居中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74952261/

相关文章:

php - Joomla 动态样式表在 css.php 文件中使用模板参数

javascript - 名称较长的条形图

javascript - 在 React JS 中更新状态

visual-studio - 命名空间 'React' 没有导出成员 'InputHTMLAttributes' 和接口(interface) 'MenuItemProps' 错误地扩展了接口(interface) 'ListItemProps'

php - CKEditor 忽略了我的 CSS

reactjs - React 组件列表中的第一个计时器正在获取值 NaN

javascript - 如何更改以更新 KonvaJS 中的属性

reactjs - 使用 Typescript 和 React.Konva 指定 onClick 事件类型

javascript - KonvaJs:具有 Angular 梯度的环

html - 为什么前两个图标的行高在 chrome 中不起作用?