Comments (5)
Hey @MatheusRoichman
rotation is not built in and if you rotate a parent, the coordinate system stays the same and you would have to do some maths, to position the child nodes correctly.
from xyflow.
What is the calculus that I need to do with the child nodes to position them correctly? I tried some, but I'm still not able to do it,
from xyflow.
What is the calculus that I need to do with the child nodes to position them correctly? I tried some, but I'm still not able to do it,
Have you tried rotating your node around the center of it's parent ?
You would use the formula
x' = x * cos(angle) - y * sin(angle)
y' = x * sin(angle) + y * cos(angle)
Applied to your case that would be:
Because the parent node is 400x400, we can think of the relative position of your child node as x:-200; y:200 from the center (Y points UP)
The angle would be 90° or PI/2 radians
The new relative position would be
x' = -200 * cos(PI/2) - 200 * sin(PI/2) = -200
y' = -200 * sin(PI/2) + 200 * cos(PI/2) = -200
You can then use this new relative position to place down your child node. IDK how your positioning system works in detail so i'll leave it here.
You will also need to rotate your child node in-place (as you are already doing) by the same angle
from xyflow.
What is the calculus that I need to do with the child nodes to position them correctly? I tried some, but I'm still not able to do it,
Have you tried rotating your node around the center of it's parent ?
You would use the formula x' = x * cos(angle) - y * sin(angle) y' = x * sin(angle) + y * cos(angle)
Applied to your case that would be: Because the parent node is 400x400, we can think of the relative position of your child node as x:-200; y:200 from the center (Y points UP)
The angle would be 90° or PI/2 radians
The new relative position would be x' = -200 * cos(PI/2) - 200 * sin(PI/2) = -200 y' = -200 * sin(PI/2) + 200 * cos(PI/2) = -200
You can then use this new relative position to place down your child node. IDK how your positioning system works in detail so i'll leave it here.
You will also need to rotate your child node in-place (as you are already doing) by the same angle
I tried it. Here's my implementation of this formula;
export const rotateNodeAroundParentCenter = (
node: Node,
angle: number,
parentCenter: XYPosition
): XYPosition => {
const x = parentCenter.x - node.position.x;
const y = parentCenter.y - node.position.y;
const angleCos = Math.cos(angle);
const angleSin = Math.sin(angle);
const newX = x * angleCos - y * angleSin;
const newY = x * angleSin + y * angleCos;
return {
x: newX,
y: newY,
};
};
export const getNodeCenter = (node: Node): XYPosition => {
const rect = getNodesBounds([node]);
return {
x: rect.width / 2,
y: rect.height / 2,
};
};
const handleRotate = useCallback(
(e: DragEvent) => {
if (!rotateControlRef.current || !resizerRef.current) return;
e.dataTransfer.effectAllowed = "none";
const rect = rotateControlRef.current.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const dx = e.clientX - centerX;
const dy = e.clientY - centerY;
const rad = Math.atan2(dy, dx);
const deg = (rad * 180) / Math.PI;
const roundedDeg = parseInt(deg.toString());
if (roundedDeg === roundedRotation) return;
setNodes((nds) =>
nds.map((node) => {
if (
!nodeOfThisElement ||
(node.id !== element.id && node.parentNode !== element.id)
)
return node;
const updatedNode = node as DesignElementNodeType;
updatedNode.data.rotation = roundedDeg;
if (updatedNode.parentNode === element.id) {
const parentCenter = getNodeCenter(nodeOfThisElement);
const childPosition = rotateNodeAroundParentCenter(
updatedNode,
roundedDeg,
parentCenter
);
updatedNode.position = childPosition;
}
return updatedNode;
})
);
setRotation(roundedDeg);
updateNodeInternals(nodeId);
},
[
element.id,
nodeId,
nodeOfThisElement,
roundedRotation,
setNodes,
updateNodeInternals,
]
);
Didn't worked well.
2024-03-08.11-37-47.online-video-cutter.com.mp4
from xyflow.
Your angle needs to be in radians and beware that the getNodeCenter() function does not return the global canvas center. For that it'd need to return x + width / 2 and y + height / 2. IDK If it's what you want though
Then I'd recommend logging x and y coordinates at different steps of the rotateAround function to see if the results are what you expect for offsetting the child. Depending on how coordinates work the implementations may differ so a simple stackoverflow copy paste might not be enough
from xyflow.
Related Issues (20)
- FitViewOptions not working with Controls component HOT 2
- nodesInitialized will fire before node measurements are exposed since xyflow 12-13 HOT 6
- Drag selection is dropped when mouse is outside the pane or when mouse encounters outside elements HOT 2
- Add "Auto Layout" example for Svelte Flow
- Node rendering inconsistent between Mac and Windows with Chrome HOT 1
- Svelte: some `SvelteFlow` component events not strongly typed HOT 2
- Add `avoidNodes` prop to getSmoothStepPath, getBezierPath and getSimpleBezierPath HOT 1
- on:connect isn't working as intend to HOT 7
- Restoring a graph with dynamic handles works sparodically HOT 8
- ConnectionDragThreshold
- Add "Reset zoom to 1" button as part of `Controls` HOT 1
- The edge style is wrong when dragging HOT 1
- Node text getting blurred when another div is scrolled (svelteflow) HOT 1
- autoLayout
- Minimap's onNodeClick doesn't work when using a custom minimap node HOT 2
- RFC - Spatial Queries & Virtualisation in XYFlow HOT 20
- Detaching a node from its parent on drag start produces unexpected positions. (v11 only) HOT 1
- Node gets unselected immediately after selecting. HOT 3
- React flow fails when execute inside a Microfrontend with Module federation
- getEdges return connections, not edges HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from xyflow.