I have an object e.g circle and I want to add more circles on border of the parent circle that must be center aligned.
On the attached gif image you can see my cursor - it only allows me to create a child circle on border of the parent.
Till now I was only able to create the parent circle.
var circle = new fabric.Circle({
strokeWidth: 1,
stroke: "#222",
noScaleCache: false,
strokeUniform: true,
scaleX: 1,
scaleY: 1,
left: canvas.getWidth() / 2,
top: canvas.getHeight() / 2,
radius: fabric.util.parseUnit(circleSize + 'in')
});
Basically you need to calculate Euclidean distance between the circle that you want to draw and the main circle, and if the distance is near to the border of the main circle you just draw a circle at the mouse position where you clicked.
The distance is calculated using Math.hypot
function.
And here is the code.
var canvas = new fabric.Canvas('c', {
selection: false
});
var circleRadius = 100;
var c = new fabric.Circle({
strokeWidth: 3,
stroke: "#222",
fill: "#55ff55",
noScaleCache: false,
strokeUniform: true,
selectable: false,
scaleX: 1,
scaleY: 1,
left: canvas.getWidth() / 2 - circleRadius,
top: canvas.getHeight() / 2 - circleRadius,
radius: circleRadius
});
canvas.add(c);
var circleAngle = Math.atan2(c.getCenterPoint().x,c.getCenterPoint().y);
var circle = new fabric.Circle({
strokeWidth: 3,
stroke: "#222",
radius: 30,
selectable: true,
originX: 'center',
originY: 'center',
fill: "#ff5555ff",
left: Math.sin(circleAngle) * circleRadius + canvas.getWidth() / 2,
top: Math.cos(circleAngle) * circleRadius + canvas.getHeight() / 2
});
canvas.add(circle);
var isDown, origX, origY;
canvas.on('mouse:down', function(o) {
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
if (isDown) {
circle.set({
strokeWidth: 3,
stroke: "#222",
radius: 30,
left: pointer.x,
top: pointer.y,
fill: "#ff5555ff"
});
canvas.add(circle);
circle = new fabric.Circle({
strokeWidth: 3,
stroke: "#222",
radius: 1,
selectable: true,
originX: 'center',
originY: 'center'
});
canvas.add(circle);
}
});
canvas.on('mouse:move', function(o) {
var pointer = canvas.getPointer(o.e);
var x = pointer.x - c.getCenterPoint().x;
var y = pointer.y - c.getCenterPoint().y;
circle.set({
strokeWidth: 3,
stroke: "#222",
radius: 30,
left: Math.sin(Math.atan2(x,y))*c.radius + canvas.getWidth() / 2,
top: Math.cos(Math.atan2(x,y))*c.radius + canvas.getHeight() / 2,
fill: "#ff5555ff"
});
if (nearToBorder(pointer, c.getCenterPoint(), c.radius)) {
isDown = true;
} else {
isDown = false;
}
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
isDown = false;
});
function nearToBorder(pointer, circlePoint, r) {
var d = Math.hypot(pointer.x - (circlePoint.x), pointer.y - (circlePoint.y));
return d >= r - 10 && d <= r + 10;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.0.0-rc.1/fabric.min.js"></script>
<canvas id="c" width="500" height="500" style="border:1px solid #ccc"></canvas>