我正在研究另一个盒子中一个盒子的可视化。
我做了改变外箱的高度,宽度,长度的道具和改变内箱尺寸的缓冲道具。
我应该如何在画布上居中绘制两个框(更改缓冲区时是外框还是内框)?
我做了高度缓冲,它起作用了,因为当我增加此值时,内部框始终在外部框的中间,但是当改变宽度或长度缓冲时,我不知道如何使它相同:/
这是我的组件代码:
import React, { Component } from 'react';
import './CanvasBox.css';
class CanvasBox extends Component {
constructor(props) {
super(props);
this.canvas = React.createRef();
this.state = {
x1: this.props.x1,
x2: this.props.x2,
y: this.props.y,
bufferLength: this.props.bufferLength || 5,
bufferWidth: this.props.bufferWidth || 5,
bufferHeight: this.props.bufferHeight || 5,
color: this.props.color || '#ff8d4b'
};
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (
this.props.x1 !== prevProps.x1 ||
this.props.x2 !== prevProps.x2 ||
this.props.y !== prevProps.y ||
this.props.bufferLength !== prevProps.bufferLength ||
this.props.bufferWidth !== prevProps.bufferWidth ||
this.props.bufferHeight !== prevProps.bufferHeight
) {
this.setState(
{
x1: this.props.x1,
x2: this.props.x2,
y: this.props.y,
bufferLength: this.props.bufferLength || 5,
bufferWidth: this.props.bufferWidth || 5,
bufferHeight: this.props.bufferHeight || 5,
color: this.props.color || '#ff8d4b'
},
this.draw()
)
}
}
componentDidMount = () => {
console.log('componentDidMount')
const ctx = this.canvas.current.getContext('2d');
console.log('ctx', ctx)
this.setState({ ctx }, () => this.draw());
};
drawCube = (x, y, wx, wy, h, color, offset) => {
const ctx = this.state.ctx;
// left side
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - wx, y - wx * 0.5);
ctx.lineTo(x - wx, y - h - wx * 0.5);
ctx.lineTo(x, y - h * 1);
ctx.closePath();
ctx.fillStyle = this.shadeColor(color, -10);
ctx.strokeStyle = color;
ctx.stroke();
ctx.fill();
// right side
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + wy, y - wy * 0.5);
ctx.lineTo(x + wy, y - h - wy * 0.5);
ctx.lineTo(x, y - h * 1);
ctx.closePath();
ctx.fillStyle = this.shadeColor(color, 10);
ctx.strokeStyle = this.shadeColor(color, 50);
ctx.stroke();
ctx.fill();
// top
ctx.beginPath();
ctx.moveTo(x, y - h);
ctx.lineTo(x - wx, y - h - wx * 0.5);
ctx.lineTo(x - wx + wy, y - h - (wx * 0.5 + wy * 0.5));
ctx.lineTo(x + wy, y - h - wy * 0.5);
ctx.closePath();
ctx.globalAlpha = 0.5;
ctx.fillStyle = this.shadeColor(color, 20);
ctx.strokeStyle = this.shadeColor(color, 60);
ctx.stroke();
ctx.fill();
};
shadeColor = (color, percent) => {
color = color.substr(1);
const num = parseInt(color, 16),
amt = Math.round(2.55 * percent),
R = (num >> 16) + amt,
G = ((num >> 8) & 0x00ff) + amt,
B = (num & 0x0000ff) + amt;
return (
'#' +
(
0x1000000 +
(R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 +
(G < 255 ? (G < 1 ? 0 : G) : 255) * 0x100 +
(B < 255 ? (B < 1 ? 0 : B) : 255)
)
.toString(16)
.slice(1)
);
};
draw = () => {
// clear the canvas
this.state.ctx.clearRect(0, 0, this.props.width, this.props.height);
// draw the cube
this.drawCube(
this.props.width/2,
this.props.height/2 + this.state.y,
Number(this.state.x1),
Number(this.state.x2),
Number(this.state.y),
'#0000',
0
);
this.drawCube(
this.props.width/2,
this.props.height/2 + this.state.y - this.state.bufferHeight,
Number(this.state.x1) - this.state.bufferLength*2,
Number(this.state.x2) - this.state.bufferWidth*2,
Number(this.state.y) - this.state.bufferHeight*2,
this.state.color,
0
);
requestAnimationFrame(this.draw);
};
render() {
return (
<div>
<canvas width={this.props.width} height={this.props.height} ref={this.canvas} />
</div>
);
}
}
export default CanvasBox;
这是我的工作示例:
https://codepen.io/robson-webdev/pen/xxxRKKM
非常感谢您的所有建议和帮助。
答案 0 :(得分:0)
我不确定100%想要什么,但这可能会有所帮助。
首先将画布原点移动到画布的中心。因此,如果您绘制诸如ctx.fillRect(-10,-10,20,20)
之类的内容,则它位于画布的中心。您可以使用ctx.setTransform(1, 0, 0, 1, ctx.canvas.width / 2, ctx.canvas.height / 2)
然后只需相对于新原点移动盒子即可。
要将原点重置到左上角ctx.setTransform(1,0,0,1,0,0);
要做我想做的事情所需的mod都可以在draw函数中完成。
draw = () => {
const state = this.state;
const ctx = state.ctx;
ctx.setTransform(1,0,0,1,0,0); // restore top left origin
ctx.clearRect(0, 0, this.props.width, this.props.height);
ctx.setTransform(1,0,0,1,ctx.canvas.width / 2, ctx.canvas.height / 2);
this.drawCube(
state.x1 / 2 - state.x2 / 2, // center x
state.x1 / 4 + state.x2 / 4 + state.y / 2, // center y
+(state.x1) ,
+(state.x2) ,
+(state.y) ,
'#0000',
0
);
const x1 = state.x1 - state.bufferLength;
const y1 = state.x2 - state.bufferWidth;
const z1 = state.y - state.bufferHeight * 2;
this.drawCube(
x1 / 2 - y1 / 2, x1 / 4 + y1 / 4 + z1/ 2,
x1, y1, z1,
state.color,
10
);
requestAnimationFrame(this.draw);
};