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

基于HTML/CSS与Flex实现可四向旋转的二维正交坐标系界面的技术求助

Simple Approach to 2D Orthonormal Frame with 4 Rotation Modes

Totally get the frustration here—getting that origin to shift correctly across four rotation modes while keeping everything aligned can feel like trying to solve a puzzle with moving pieces. Let's break down a straightforward, maintainable approach using plain CSS that avoids overcomplicating things, and keeps your workspace content readable (no unwanted rotations).

Core Idea

We'll use a container for the entire frame, with data attributes to toggle between rotation modes. Axes are positioned absolutely relative to the container's corners, and we adjust their orientation using CSS transforms and writing-mode where needed. The workspace stays unrotated, positioned in the "positive quadrant" relative to the origin corner for each mode.

Example Code

First, the HTML structure:

<div class="coordinate-frame" data-mode="0">
  <div class="axis x-axis">X</div>
  <div class="axis y-axis">Y</div>
  <div class="workspace">
    <!-- Your content here (won't be rotated!) -->
    <div class="content">Workspace Content</div>
  </div>
</div>

Then the CSS:

/* Base container styles */
.coordinate-frame {
  width: 400px;
  height: 300px;
  border: 2px solid #333;
  position: relative;
  margin: 20px;
}

/* Axis base styles */
.axis {
  position: absolute;
  background: #2196F3;
  color: white;
  padding: 0 5px;
  font-size: 14px;
}

.x-axis { height: 20px; line-height: 20px; }
.y-axis { width: 20px; text-align: center; }

/* Workspace styles (content stays unrotated) */
.workspace {
  position: absolute;
  background: rgba(100, 200, 255, 0.2);
  border: 1px dashed #2196F3;
}

.content { padding: 10px; color: #333; }

/* Mode 0: Origin top-left (X right, Y down) */
.coordinate-frame[data-mode="0"] .x-axis {
  top: 0; left: 0;
  width: calc(100% - 20px); /* Leave space for Y axis */
}
.coordinate-frame[data-mode="0"] .y-axis {
  top: 0; left: 0;
  height: calc(100% - 20px); /* Leave space for X axis */
}
.coordinate-frame[data-mode="0"] .workspace {
  top: 20px; left: 20px;
  width: calc(100% - 20px); height: calc(100% - 20px);
}

/* Mode 90: Origin top-right (X down, Y left) */
.coordinate-frame[data-mode="90"] .x-axis {
  top: 0; right: 0;
  width: 20px; height: calc(100% - 20px);
  writing-mode: vertical-rl; /* Rotate text for vertical axis */
}
.coordinate-frame[data-mode="90"] .y-axis {
  top: 0; right: 20px;
  width: calc(100% - 20px); height: 20px;
  transform: rotate(180deg); /* Flip text to point left */
}
.coordinate-frame[data-mode="90"] .workspace {
  top: 20px; right: 20px;
  width: calc(100% - 20px); height: calc(100% - 20px);
}

/* Mode 180: Origin bottom-right (X left, Y up) */
.coordinate-frame[data-mode="180"] .x-axis {
  bottom: 0; right: 20px;
  width: calc(100% - 20px); height: 20px;
  transform: rotate(180deg); /* Flip text to point left */
}
.coordinate-frame[data-mode="180"] .y-axis {
  bottom: 0; right: 0;
  width: 20px; height: calc(100% - 20px);
  writing-mode: vertical-rl; transform: rotate(180deg); /* Flip text to point up */
}
.coordinate-frame[data-mode="180"] .workspace {
  bottom: 20px; right: 20px;
  width: calc(100% - 20px); height: calc(100% - 20px);
}

/* Mode 270: Origin bottom-left (X up, Y right) */
.coordinate-frame[data-mode="270"] .x-axis {
  bottom: 0; left: 0;
  width: 20px; height: calc(100% - 20px);
  writing-mode: vertical-rl; transform: rotate(180deg); /* Flip text to point up */
}
.coordinate-frame[data-mode="270"] .y-axis {
  bottom: 20px; left: 0;
  width: calc(100% - 20px); height: 20px;
}
.coordinate-frame[data-mode="270"] .workspace {
  bottom: 20px; left: 20px;
  width: calc(100% - 20px); height: calc(100% - 20px);
}

Key Details

  • Mode Switching: Just change the data-mode attribute on the container to 0, 90, 180, or 270 to toggle the origin and axis directions.
  • Unrotated Workspace: Unlike rotating the entire frame, this approach keeps your workspace content (text, images, etc.) in its natural orientation—critical for usability.
  • Maintainable: Each mode's styles are grouped together, so it's easy to adjust axis sizes, colors, or workspace positioning without breaking other modes.

Customization Tips

  • Adjust axis size: Change the height/width values on .x-axis/.y-axis and update the corresponding calc() values to match.
  • Add tick marks: Use pseudo-elements (::before/::after) on the axes to add scale ticks.
  • Dynamic sizing: Replace fixed container dimensions with percentages or max-width/max-height for responsiveness.

内容的提问来源于stack exchange,提问作者AhqueCoucou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 14:02:39