如何围绕对象边角旋转?D3旋转默认锚点及线段端点旋转咨询
To rotate an element around one of its corners (or any specific point), you need to adjust the rotation anchor—since SVG's default rotation origin is the top-left corner of the SVG canvas (0,0) unless specified otherwise. Here's how to do it:
Method 1: Use the 3-parameter rotate() transform
The simplest way is to use SVG's built-in rotate(angle, cx, cy) function, where cx and cy are the coordinates of the corner (or pivot point) you want to rotate around. This handles all the translation math for you automatically.
For example, if you have a rectangle at (x: 20, y: 20) with width 100 and height 60, and you want to rotate it 45 degrees around its bottom-right corner (120, 80):
const rect = svg.append("rect") .attr("x", 20) .attr("y", 20) .attr("width", 100) .attr("height", 60) .attr("fill", "steelblue"); // Rotate 45 degrees around bottom-right corner (20+100, 20+60) rect.attr("transform", "rotate(45, 120, 80)");
Method 2: Manual translate-rotate-translate
If you want to understand the underlying math, you can chain three transforms (applied right-to-left):
- Translate the element so the pivot point moves to the origin (
translate(-cx, -cy)). - Apply the rotation (
rotate(angle)). - Translate the element back to its original position relative to the pivot (
translate(cx, cy)).
Using the same rectangle example:
rect.attr("transform", "translate(120, 80) rotate(45) translate(-120, -80)");
Default Rotation Anchor
In D3 (which uses SVG transforms under the hood), the default anchor point for rotate() (when you only specify the angle) is the origin (0,0) of the current coordinate system. For elements that haven't been translated, this is the top-left corner of the SVG canvas. If the element already has a transform applied, the origin is relative to that transformed space.
Rotating a Line Around Its Endpoint
To rotate a line around one of its endpoints, use the 3-parameter rotate() transform, setting cx and cy to the coordinates of the endpoint you want to pivot around. Here's a cleaned-up working example based on your code snippet:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>D3: Rotate Line Around Endpoint</title> <script src="https://d3js.org/d3.v4.min.js"></script> </head> <body> <svg width="400" height="300"></svg> <script> const svg = d3.select("svg"); // Create a horizontal line from (50, 150) to (250, 150) const line = svg.append("line") .attr("x1", 50) .attr("y1", 150) .attr("x2", 250) .attr("y2", 150) .attr("stroke", "black") .attr("stroke-width", 2); // Rotate the line 90 degrees around its left endpoint (50, 150) const rotationAngle = 90; const pivotX = 50; // x1 of the line const pivotY = 150; // y1 of the line line.attr("transform", `rotate(${rotationAngle}, ${pivotX}, ${pivotY})`); </script> </body> </html>
This will rotate the line 90 degrees counterclockwise around its left endpoint. If you want to rotate around the right endpoint instead, just set pivotX to 250 and pivotY to 150.
内容的提问来源于stack exchange,提问作者santoku

