我目前正在 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>
这就是输出的渲染方式。
我将包装器的背景着色为蓝色,以显示图像应在哪个框中居中。
我已经在“mycanvas”、“stage”和“meme”类以及“konvajs-content”(由于某种原因出现在我的检查器中)上尝试过CSS。我使用过align-items: center、margin: auto 和其他一些,但我认为普通的CSS 在这里并不适用。 我认为这是关于 konvajs 组件的一般样式的问题,但不幸的是我在 stackoverflow 或 konva 文档上找不到任何解决方案。
最佳答案
这是 CSS 无法提供帮助的情况。当使用您提供的 x
和 y
坐标处的高度和宽度将图像应用到 Canvas 时,图像的像素将成为光栅化 Canvas 的一部分。换句话说,图像并不独立于 Canvas 而存在。
因此,如果您想让图像在 Canvas 内居中,您需要做一些数学计算来计算放置图像的 x
和 y
坐标位于 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/