You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Canvas绘制的嵌套立方体始终保持居中?

Fixing Inner Cube Centering for Width/Length Axes

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

  1. 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 when x1 and x2 are unequal.
  2. Removed Infinite Re-render: The requestAnimationFrame(this.draw) call was causing non-stop redrawing even when no props or state changed. Since componentDidMount and componentDidUpdate already trigger draw when needed, we can safely remove this to save performance.
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:21:11