KonvaJS 变换围绕 SVG 中心的旋转
KonvaJS transform rotation around center on SVG
我使用 KonvaJS
在 canvas 上创建文本。我可以使用 Transformer 冻结文本。绘图时,原点保持在中心,我希望这里没有问题。
但是,当我想在这里使用带有svg的数据时,x
和y
不冻结就实现了。但是当我做冰淇淋时,它会在中心外结冰。这里
transform={{
rotation: 90,
originX: x + width / 2,
originY: y + height / 2,
}}
当我冻结使用它时它起作用了。因为 x 和 y 值没有改变。但是,在 KonvJs 上绘制时,如果我冻结,xtation
和 y
的值会随着 ratation
的值一起变化。
缩短示例之间的代码。
import React, { Fragment, useEffect, useRef } from 'react'
import { Text, Transformer } from 'react-konva'
import { useStore } from './store'
export default function ({ id, text }) {
const { regions, selected, setRegions, setSelected } = useStore()
const { x, y, value, color, rotation, fontSize } = text
const TextRef = useRef()
const TransformRef = useRef()
const onDragEnd = ({ target }) => {
setRegions(
regions.map((item) => {
if (item.id === id) {
item.text = {
...item.text,
x: target.x(),
y: target.y(),
width: target.width(),
height: target.height(),
}
}
return item
})
)
}
const onTransformEnd = () => {
const node = TextRef.current
const width = node.width()
const height = node.height()
const x = node.x()
const y = node.y()
const rotation = node.rotation()
const originX = x + width / 1.3
const originY = y + height / 1.3
setRegions(
regions.map((item) => {
if (item.id === id) {
item.text = {
...item.text,
x, // <= it changes when this is rotation
y, // <= it changes when this is rotation
rotation,
originX,
originY,
}
}
return item
})
)
}
const isSelected = id === selected
useEffect(() => {
if (isSelected) {
TransformRef.current.setNode(TextRef.current)
TransformRef.current.getLayer().batchDraw()
}
}, [isSelected])
return (
<Fragment>
<Text
draggable
name="region"
x={x}
y={y}
text={value}
fill={color}
ref={TextRef}
rotation={rotation}
fontSize={fontSize}
onDragEnd={onDragEnd}
onTransformEnd={onTransformEnd}
/>
{isSelected && (
<Transformer
ref={TransformRef}
/>
)}
</Fragment>
)
}
在约定中给出偏移量就足以在我所做的部分中工作。重要的例子是我可以在客户端用 svg 显示。反应本机 Svg
<G
transform={{
rotation: rotation,
originX: x + width / 2,
originY: y + height / 2,
}}>
<Text
x={x}
y={y}
fill={'#fff'}
fontSize={fontSize}
textAnchor="start"
>
{value}
</Text>
</G>
您可能需要计算形状的中心,以便在 SVG 中正确定位它。
function getCenter(shape) {
return {
x:
shape.x +
(shape.width / 2) * Math.cos(shape.rotation) +
(shape.height / 2) * Math.sin(-shape.rotation),
y:
shape.y +
(shape.height / 2) * Math.cos(shape.rotation) +
(shape.width / 2) * Math.sin(shape.rotation)
};
}
function Show({ text, x, y, rotation, width, height }) {
const center = getCenter({
x,
y,
width,
height,
rotation: (rotation / 180) * Math.PI
});
return (
<svg width={window.innerWidth} height={window.innerHeight / 2}>
<text
y={height / 1.3}
fill="#000"
fontSize={50}
alignment-baseline="bottom"
transform={`translate(${x}, ${y}) rotate(${rotation})`}
>
{text}
</text>
{/* Origin Circl */}
<circle cx={center.x} cy={center.y} r={10} fill="red" />
</svg>
);
}
演示:https://codesandbox.io/s/konva-and-svg-demo-jx7sj?file=/src/Playground.js:1704-2583
我使用 KonvaJS
在 canvas 上创建文本。我可以使用 Transformer 冻结文本。绘图时,原点保持在中心,我希望这里没有问题。
但是,当我想在这里使用带有svg的数据时,x
和y
不冻结就实现了。但是当我做冰淇淋时,它会在中心外结冰。这里
transform={{
rotation: 90,
originX: x + width / 2,
originY: y + height / 2,
}}
当我冻结使用它时它起作用了。因为 x 和 y 值没有改变。但是,在 KonvJs 上绘制时,如果我冻结,xtation
和 y
的值会随着 ratation
的值一起变化。
缩短示例之间的代码。
import React, { Fragment, useEffect, useRef } from 'react'
import { Text, Transformer } from 'react-konva'
import { useStore } from './store'
export default function ({ id, text }) {
const { regions, selected, setRegions, setSelected } = useStore()
const { x, y, value, color, rotation, fontSize } = text
const TextRef = useRef()
const TransformRef = useRef()
const onDragEnd = ({ target }) => {
setRegions(
regions.map((item) => {
if (item.id === id) {
item.text = {
...item.text,
x: target.x(),
y: target.y(),
width: target.width(),
height: target.height(),
}
}
return item
})
)
}
const onTransformEnd = () => {
const node = TextRef.current
const width = node.width()
const height = node.height()
const x = node.x()
const y = node.y()
const rotation = node.rotation()
const originX = x + width / 1.3
const originY = y + height / 1.3
setRegions(
regions.map((item) => {
if (item.id === id) {
item.text = {
...item.text,
x, // <= it changes when this is rotation
y, // <= it changes when this is rotation
rotation,
originX,
originY,
}
}
return item
})
)
}
const isSelected = id === selected
useEffect(() => {
if (isSelected) {
TransformRef.current.setNode(TextRef.current)
TransformRef.current.getLayer().batchDraw()
}
}, [isSelected])
return (
<Fragment>
<Text
draggable
name="region"
x={x}
y={y}
text={value}
fill={color}
ref={TextRef}
rotation={rotation}
fontSize={fontSize}
onDragEnd={onDragEnd}
onTransformEnd={onTransformEnd}
/>
{isSelected && (
<Transformer
ref={TransformRef}
/>
)}
</Fragment>
)
}
在约定中给出偏移量就足以在我所做的部分中工作。重要的例子是我可以在客户端用 svg 显示。反应本机 Svg
<G
transform={{
rotation: rotation,
originX: x + width / 2,
originY: y + height / 2,
}}>
<Text
x={x}
y={y}
fill={'#fff'}
fontSize={fontSize}
textAnchor="start"
>
{value}
</Text>
</G>
您可能需要计算形状的中心,以便在 SVG 中正确定位它。
function getCenter(shape) {
return {
x:
shape.x +
(shape.width / 2) * Math.cos(shape.rotation) +
(shape.height / 2) * Math.sin(-shape.rotation),
y:
shape.y +
(shape.height / 2) * Math.cos(shape.rotation) +
(shape.width / 2) * Math.sin(shape.rotation)
};
}
function Show({ text, x, y, rotation, width, height }) {
const center = getCenter({
x,
y,
width,
height,
rotation: (rotation / 180) * Math.PI
});
return (
<svg width={window.innerWidth} height={window.innerHeight / 2}>
<text
y={height / 1.3}
fill="#000"
fontSize={50}
alignment-baseline="bottom"
transform={`translate(${x}, ${y}) rotate(${rotation})`}
>
{text}
</text>
{/* Origin Circl */}
<circle cx={center.x} cy={center.y} r={10} fill="red" />
</svg>
);
}
演示:https://codesandbox.io/s/konva-and-svg-demo-jx7sj?file=/src/Playground.js:1704-2583