如何让Canvas绘制的嵌套立方体始终保持居中?
Hey there! Let's get that inner cube centered properly along the width and length axes. The issue right now is that we're keeping the inner cube's horizontal starting position the same as the outer cube, but since we've shrunk the inner cube's width/length buffers, we need to adjust its horizontal offset to maintain perfect centering.
Root Cause
The outer cube's visual center isn't exactly at this.props.width/2 unless x1 (length) and x2 (width) are equal. When we shrink the inner cube by subtracting buffers, we have to compensate for the difference between the original and reduced dimensions to keep the inner cube aligned with the outer cube's center.
Solution
Adjust the horizontal position of the inner cube by calculating an offset based on the buffer values. Here's how to modify your draw method:
draw = () => { // Clear the canvas this.state.ctx.clearRect(0, 0, this.props.width, this.props.height); // Calculate outer cube properties for clarity const outerX = this.props.width/2; const outerY = this.props.height/2 + this.state.y; const outerLength = Number(this.state.x1); const outerWidth = Number(this.state.x2); const outerHeight = Number(this.state.y); // Draw outer cube this.drawCube( outerX, outerY, outerLength, outerWidth, outerHeight, '#0000', 0 ); // Calculate inner cube properties and centering offsets const innerLength = outerLength - this.state.bufferLength * 2; const innerWidth = outerWidth - this.state.bufferWidth * 2; const innerHeight = outerHeight - this.state.bufferHeight * 2; // Horizontal offset to align inner cube's center with outer cube's center const horizontalOffset = (this.state.bufferWidth - this.state.bufferLength); const innerX = outerX + horizontalOffset; // Vertical offset (your existing logic already works for centering!) const innerY = outerY - this.state.bufferHeight; // Draw inner cube this.drawCube( innerX, innerY, innerLength, innerWidth, innerHeight, this.state.color, 0 ); // Remove infinite requestAnimationFrame - it causes unnecessary continuous re-renders // requestAnimationFrame(this.draw); };
Key Changes Explained
- Horizontal Offset Calculation:
horizontalOffset = (bufferWidth - bufferLength)adjusts the inner cube's X position to account for the difference in how much we've shrunk the width vs length sides. This ensures the inner cube's visual center matches the outer cube's center, even whenx1andx2are unequal. - Removed Infinite Re-render: The
requestAnimationFrame(this.draw)call was causing non-stop redrawing even when no props or state changed. SincecomponentDidMountandcomponentDidUpdatealready triggerdrawwhen needed, we can safely remove this to save performance. - Clean Variable Naming: Breaking out properties into descriptive named variables makes the code easier to read, debug, and modify later.
Quick Check
Double-check that your componentDidUpdate correctly triggers draw after state updates—your current implementation passing this.draw() as the setState callback is correct, ensuring state is fully updated before redrawing.
内容的提问来源于stack exchange,提问作者Robson

