Я работаю над визуализацией блока внутри другого блока.
Я сделал реквизиты для изменения высоты, ширины, длины внешнего блока и буферные реквизиты для изменения размера внутреннего блока.
Как мне нарисовать оба блока по центру холста (внешний блок и внутренний блок при смене буферов)?
Я сделал буфер высоты, и он работает, я думаю, потому что, когда я увеличиваю это значение,Внутренний блок всегда находится в середине внешнего блока, но не могу понять, как сделать его таким же, когда я изменяю ширину или длину буфера: /
Вот мой код компонента:
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
Большое спасибо за все советы и помощь.