A visualization library experiment for interactive website effects based on pathfinding algorithms
Initialize PathfindingFX by instantiating a new PathfindingFX Object and pass in the element where the canvas should be drawn into.
As a second parameter pass the map with a two-dimensional array giving information about what is a wall and what not.
const PFX = new PathfindingFX(
document.getElementById("pfx-init"),
[
],
);
Adds nodes to the canvas. The addNode method accepts an object of settings. The most important one is the "pos" property which includes a x and y position based on the current map (starting from zero in the top left corner).
There are more settings, for example the style property defining the shape and color of the node.
const PFX = new PathfindingFX([...]);
const nodeA = ;
const nodeB = ;
PFX.addNode(nodeA);
PFX.addNode(nodeB);
Every added node can have its path calculated by giving it a "to" property containing the "pos" to which x/y point the path should be found.
Like a node itself, the "to" property can have more settings like, again, a style property.
const PFX = new PathfindingFX([...]);
const node = {[...],
to:
};
PFX.addNode(node);
Give a node a "to" and "speed" property and call the "play()" method on the PFX object to start the auto play.
Try dragging around the node, its goal or just hit the button below.
const PFX = new PathfindingFX([...]);
const node = {[...],
to: [...],
speed: 100,
};
PFX.addNode(node);
PFX.play();
Every nodes "positions()" method returns an array of accessible positions for that node. These positions contain different values about how far that position is away.
With the help of callbacks like onRender we can modify the drawn canvas by creative ways.
const PFX = new PathfindingFX([...]);
const node = {[...],
onRender: (node) => {
node
.positions()
.filter((n) => n.g <= )
.map((n) => {
PFX.drawNode({
pos: n.pos
style: { color: "#E1D7C6" },
});
});
},
};
PFX.addNode(node);
You can also use other map values than 0 and 1. By using higher values you give each position a weight which will be considered by the calculation.
The algorithm always wants to find the way with the lowest weight in total. You can modify the values in this example.
const PFX = new PathfindingFX([...],
[
]
);
PFX.addNode({
[...],
allowDiagonal: false
});
const PFX = new PathfindingFX(element,map,
{
// Algorithm
heuristics: "manhattan", // used heuristics, can be "manhattan" or "euclidean"
allowDiagonal: true, // globally set if diagonal movement is allowed
// Colors
wallNodeColor: "#dbdbdb", // color of nodes with value "0" (walls)
emptyNodeColor: "#f8f8f8", // color of nodes with value "1" (walkable)
pathNodeColor: "#a8a8a8", // color of paths that aren't colored otherwise
highlightEdges: true, // if walls should have edges
wallEdgeColor: "#a8a8a8", // if above is true, this color is used
weightNodeColors: { // in case of weighted map, these colors are used for different weights
5: { color: "#6c584c" },
4: { color: "#a98467" },
3: { color: "#adc178" },
2: { color: "#dde5b6" },
1: { color: "#f0ead2" },
0: { color: "#0088bb", edgeColor: "#c2b280" },
}
// Interactivity
interactive: true, // defines if the map is interactive with cursor or touch events
// Callbacks
onUpdateMap: function(newMap), // callback function when the map updates
onInteractionWithAFreeNode: function(node,pos,pfx_instance), // callback function when interacting with free nodes
onInteractionWithAWallNode: function(node,pos,pfx_instance), // callback function when interacting with wall nodes
}
)
PFX.addNode(
{
// Algorithm
pos: { // initial x and y position (0,0 is in the top left corner)
x: 0,
y: 0
},
to: {
pos: { // position to which the path gets calculated and rendered
x: 0,
y: 0
},
style: [See below, same as node styling]
},
allowDiagonal: true, // allows diagonal movement (this overrides global settings)
// Colors
style: {
color: "#000000", // color of the node
shape: "rect", // shape of the node ("rect", "circle" "roundRect")
mode: "fill", // drawing mode of the node ("fill", "stroke")
size: {
w: 1 // width of the node, factored to the tile size. (1 equals 100% of the given tiles space)
h: 1 // height of the node, factored to the tile size. (1 equals 100% of the given tiles space)
}
},
// Interactivity
interactive: true, // defines if a node is interactive with cursor or touch events
// Animation
speed: 100, // when using PFX.play() this number defines how quickly the node follows its path
// Callbacks
onAdd: function(node), // callback function when a node gets added
onRender: function(node), // callback function when a node gets rendered in the global render function
onUpdate: function(node,delta), // callback function when a nodes gets updated in the global animation update function
onPosChange: function(node,pos), // callback function when a nodes position changes
onPathEnd: function(node), // callback function when the node reaches its goal
onNoPath: function(node), // callback function a node has no path
}
)
// Animation
PFX.play() // enables animation and will automatically update nodes positions
PFX.stop() // disables animation
// Miscellaneous
PFX.reset() // resets everything and removes the canvas from the DOM
Designed with
TailwindCSS
Interactions realized with
Alpine