Skip to content

Commit 8bc9584

Browse files
committed
Animate node movement
1 parent 177839b commit 8bc9584

File tree

1 file changed

+39
-11
lines changed

1 file changed

+39
-11
lines changed

src/render.js

+39-11
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,25 @@ import * as utils from "./utils";
44
export const moveTree = (tree, dx = 0, dy = 0) => {
55
if (dx === 0 && dy === 0) return;
66
BST.breadthFirstTraverse(tree, (item) => {
7-
item.extras.x += dx;
8-
item.extras.x += dy;
7+
item.extras.dx += dx;
8+
item.extras.dy += dy;
9+
item.extras.transitioned = false;
10+
item.extras.moveMultiplier = 0;
911
});
1012
};
1113

1214
export const fixCollisions = (visualizer, node) => {
1315
let parent = node.parent;
1416
const { padding, radius } = visualizer;
1517
while (parent) {
16-
if (node.value > parent.value && node.extras.x <= parent.extras.x) {
17-
moveTree(parent.right, (parent.extras.x - node.extras.x + padding + radius * 2));
18+
if (node.value > parent.value && node.extras.dx <= parent.extras.dx) {
19+
moveTree(parent.right, (parent.extras.dx - node.extras.dx + padding + radius * 2));
1820
BST.breadthFirstTraverse(parent.right, (item) => {
1921
fixCollisions(visualizer, item);
2022
});
2123
break;
22-
} else if (node.value < parent.value && node.extras.x >= parent.extras.x) {
23-
moveTree(parent.left, -(node.extras.x - parent.extras.x + padding + radius * 2));
24+
} else if (node.value < parent.value && node.extras.dx >= parent.extras.dx) {
25+
moveTree(parent.left, -(node.extras.dx - parent.extras.dx + padding + radius * 2));
2426
BST.breadthFirstTraverse(parent.left, (item) => {
2527
fixCollisions(visualizer, item);
2628
});
@@ -32,11 +34,10 @@ export const fixCollisions = (visualizer, node) => {
3234

3335
export const calculateNodePosition = (visualizer, node, parent) => {
3436
const { radius, padding, dimensions } = visualizer;
35-
3637
return parent
3738
? {
38-
x: parent.extras.x + (parent.left === node ? -1 : +1) * (padding + radius * 2),
39-
y: parent.extras.y + padding + radius * 2
39+
x: parent.extras.dx + (parent.left === node ? -1 : +1) * (padding + radius * 2),
40+
y: parent.extras.dy + padding + radius * 2
4041
} : {
4142
x: 0,
4243
y: -(dimensions.height / 2) + padding + radius
@@ -49,8 +50,15 @@ export const updateNode = (visualizer, node, parent = null) => {
4950
if (!node.extras.initialized) {
5051
node.extras.multiplier = 0;
5152
const {x, y} = calculateNodePosition(visualizer, node, parent);
52-
node.extras.x = x;
53-
node.extras.y = y;
53+
54+
node.extras.sx = x;
55+
node.extras.sy = y;
56+
node.extras.x = x;
57+
node.extras.y = y;
58+
node.extras.dx = x;
59+
node.extras.dy = y;
60+
node.extras.transitioned = true;
61+
node.extras.moveMultiplier = 0;
5462
// TODO: Find a better place to call these 2 functions
5563
fixCollisions(visualizer, node);
5664
utils.updateCameraBounds(visualizer);
@@ -60,6 +68,26 @@ export const updateNode = (visualizer, node, parent = null) => {
6068
node.extras.multiplier += 0.06;
6169
if (node.extras.multiplier > 1) node.extras.entered = true;
6270
}
71+
72+
if (!node.extras.transitioned) {
73+
const { sx, sy, dx, dy, moveMultiplier } = node.extras;
74+
if (moveMultiplier >= 1) {
75+
node.extras.transitioned = true;
76+
node.extras.sx = dx;
77+
node.extras.sy = dy;
78+
node.extras.x = dx;
79+
node.extras.y = dy;
80+
node.moveMultiplier = 0;
81+
return;
82+
}
83+
const distance = utils.distance(sx, dx, sy, dy) * moveMultiplier;
84+
const angle = utils.angle(dx, sx, dy, sy);
85+
86+
node.extras.x = node.extras.sx + distance * Math.cos(angle);
87+
node.extras.y = node.extras.sy + distance * Math.sin(angle);
88+
89+
node.extras.moveMultiplier += 0.06;
90+
}
6391
}
6492

6593
updateNode(visualizer, node.left, node);

0 commit comments

Comments
 (0)