I have a path with 4 points. I'd like these points to follow objects that I drag around the screen.
I tried updating the path points during the canvas.on('object:moving') so that while an object is being dragged, the path property of my path is being updated. But as soon as I move the objects, the path disappears.
//call the function to update the path points string, then set the path property
updateUpperArmPath();
upperArmPath.set({
path: upperArmPathPoints
});
//update the upper arm path function
function updateUpperArmPath() {
pointString = createPathString([
{x: originCircle.left - originCircle.radius, y: originCircle.top},
{x: originCircle.left + originCircle.radius, y: originCircle.top},
{x: jointCircle.left + jointCircle.radius, y: jointCircle.top},
{x: jointCircle.left - jointCircle.radius, y: jointCircle.top}
]);
upperArmPathPoints = pointString;
}
//function to automatically create a path string from an array of points
function createPathString(points) {
var pathString = '';
for (var i = 0; i < points.length; i++) {
var point = points[i];
var command = i === 0 ? 'M' : 'L';
pathString += ' ' + command + ' ' + point.x + ' ' + point.y;
}
pathString += ' Z';
return pathString;
}
The value passed to the path property must be in the following form:
[
["M",100,100],
["L",300,100],
["L",300,300],
["L",100,300],
["Z"]
]
Instead of a string: " M 100 100 L 300 100 L 300 300 L 100 300 Z"
Working demo (and updated code):
let canvas = new fabric.Canvas("canvas", {
width: 500,
height: 500,
selection: false
});
var circle1;
var circle2;
var circle3;
var circle4;
var pathPoints = [];
var path;
canvas.on("object:moving", setPath);
canvas.on("object:modified", setPath);
circle1 = new fabric.Circle({
radius: 20,
fill: "#ff0000",
left: 100,
top: 100,
originX: "center",
originY: "center",
hasControls: false
});
circle2 = new fabric.Circle({
radius: 20,
fill: "#00ff00",
left: 300,
top: 100,
originX: "center",
originY: "center",
hasControls: false
});
circle3 = new fabric.Circle({
radius: 20,
fill: "#0000ff",
left: 300,
top: 300,
originX: "center",
originY: "center",
hasControls: false
});
circle4 = new fabric.Circle({
radius: 20,
fill: "#880088",
left: 100,
top: 300,
originX: "center",
originY: "center",
hasControls: false
});
updatePathPoints();
path = new fabric.Path(pathPoints, {
fill: "#ffffff",
selectable: false
});
canvas.add(circle1, circle2, circle3, circle4, path);
canvas.renderAll();
//create path string from array of points
function createPathArray(points) {
var pathArray = [];
for (var i = 0; i < points.length; i++) {
var point = points[i];
var command = i === 0 ? "M" : "L";
pathArray.push([command, point.x, point.y])
}
pathArray.push(["Z"]);
return pathArray;
}
const pathArray = [];
function updatePathPoints() {
pathPoints = createPathArray([
{ x: circle1.left, y: circle1.top },
{ x: circle2.left, y: circle2.top },
{ x: circle3.left, y: circle3.top },
{ x: circle4.left, y: circle4.top }
]);
circle1.setCoords();
circle2.setCoords();
circle3.setCoords();
circle4.setCoords();
}
function setPath() {
updatePathPoints();
console.log(pathPoints);
path.set({ path: pathPoints });
canvas.renderAll();
}
body {
font-family: system-ui;
background: #f06d06;
color: white;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<div style="text-align: center;">
<canvas id="canvas"></canvas>
</div>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With