【发布时间】:2019-01-12 06:36:38
【问题描述】:
首先,感谢您花时间回答我的问题。
我正在为一个小型图像编辑器项目工作,基于 konva.js 和 react。但是我遇到了一些问题,困扰了我几天。 我想使用组的旋转属性来旋转组和其中的所有形状,当单击旋转按钮时,它可以正常工作,但是当我单击文本按钮并想在图像上绘制它并重新定位时确切地说,pic1 是我的预期结果,但实际上,我得到了意想不到的结果显示为 pic2,我该怎么做才能准确地旋转组和其中的所有形状。
我的简单示例如下所示:
class Test extends React.Component{
constructor(props) {
super(props)
this.state = {
historyArray: [],
isTexting: true,
image: new window.Image(),
layerPos:{
x: 300,
y: 100,
},
imageWidth: 0,
imageHeight: 0,
rotateDegrees: 0,
}
}
componentDidMount() {
const {historyArray} = this.state;
this.state.image.setAttribute("crossOrigin", "anonymous");
this.state.image.src = "https://vd.youniwote.com/homework/44evmey2cbd/submit/44evmey2cbe.jpg";
this.state.image.onload = () => {
let imageWidth = this.state.image.width > 620 ? 620 / (parseFloat(this.state.image.height) / parseFloat(this.state.image.width)) : this.state.image.width;
let imageHeight = this.state.image.height > 620 ? 620 : this.state.image.height;
let imageObj = {
mode: 'image',
image: this.state.image,
width: imageWidth,
height: imageHeight,
}
historyArray.push(imageObj);
this.setState({
historyArray,
imageWidth,
imageHeight,
})
}
}
clickStage = (event) => {
const {mode, isTexting, historyArray} = this.state;
if (mode == 'text') {
if (isTexting) {
let textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.style.position = 'absolute';
textarea.style.top = event.evt.pageY + 'px';
textarea.style.left = event.evt.pageX + 'px';
textarea.style.width = 100;
textarea.focus();
this.setState({
isTexting: false,
})
textarea.addEventListener('keydown', (e) => {
if (e.keyCode === 13) {
historyArray.push({
mode: "text",
x:this.getActualPosInStage(event).x,
y: this.getActualPosInStage(event).y,
text: textarea.value,
})
document.body.removeChild(textarea);
this.setState({
isTexting: true,
historyArray
})
}
});
}
}
}
getActualPosInStage = (e) => {
const {layerPos} = this.state;
let stageBox = this.stage.getStage().getContainer().getBoundingClientRect();
let mousePos = {
x: e.evt.clientX,
y: e.evt.clientY,
}
let x = Math.abs(mousePos.x - stageBox.left - layerPos.x);
let y = Math.abs(mousePos.y - stageBox.top - layerPos.y);
return {x,y}
}
render() {
return (
<div>
<div style={{top: 0, left: 0}}>
<Button onClick={() => {
this.setState({
mode: 'text',
groupDraggable: false,
})
}}>Text</Button>
<Button style={{marginLeft: 20}} onClick={() => {
const {rotateDegrees} = this.state;
this.setState({
rotateDegrees: rotateDegrees + 90,
groupDraggable: false,
mode: 'rotate',
})
this.group.offsetX(this.group.width() / 2);
this.group.offsetY(this.group.height() / 2);
this.group.x(this.group.width() / 2);
this.group.y(this.group.height() / 2);
}}>Rotate</Button>
</div>
<Stage
onClick={(e) => {this.clickStage(e)}}
width={1000}
height={1000}
ref={node => {
this.stage = node;
}}
>
<Layer
x={this.state.layerPos.x}
y={this.state.layerPos.y}
ref={node => {
this.layer = node;
}}
>
<Group
rotation={this.state.rotateDegrees}
width={this.state.imageWidth}
height={this.state.imageHeight}
ref={node => {
this.group = node;
}}
>
{
this.state.historyArray.map((item, index) => {
if (item.mode == 'image') {
return (
<Image
key={index}
width={item.width}
height={item.height}
image={this.state.image}
ref={node => {
this.imageNode = node;
}}
/>
)
} else if (item.mode == 'text') {
return(
<Text
key={index}
x={item.x}
y={item.y}
text={item.text}
fontSize={24}
fill='red'
/>
)
}
})
}
</Group>
</Layer>
</Stage>
</div>
)
}
}
这些问题困扰了我好几天,如果有人能回答我的问题,我会感谢它
【问题讨论】:
-
这里有一些关于转换共享的信息:longviewcoder.com/2021/01/12/…
标签: konvajs