如何在 fabricjs 中添加没有重叠的随机圆 canvas
how to add random circles with no overlap inside a fabricjs canvas
我正在尝试提出一种算法,在 fabricj canvas; 中添加 没有重叠的随机圆
下面的片段是我试过的。
const canvas = new fabric.Canvas('gameCanvas', {selection: false});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
let rectangle;
document.addEventListener('DOMContentLoaded', function(){
rectangle = new fabric.Rect({
width: 250,
height: 100,
fill: 'blue',
opacity: 0.2,
left: 200,
top: 140
});
canvas.add(rectangle);
});
document.getElementById('addCirclesBtn').addEventListener('click', function(){
drawCircles();
});
function drawCircles()
{
for(let i = 1; i <=20; i++)
{
let x= Math.random() * (rectangle.width - rectangle.left) + rectangle.left;
let y = Math.random() * (rectangle.height - rectangle.top) + rectangle.top;
let circle = new fabric.Circle({
left: x,
top: y,
strokeWidth: 2,
radius: 10,
fill: 'white',
stroke: '#666',
selectable: false,
hoverCursor: 'default',
hasControls: false,
hasBorders: false
});
canvas.add(circle);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.0.0/fabric.min.js"></script>
<canvas id="gameCanvas" width="500" height="300" style="border: 2px solid green;"></canvas>
<button id="addCirclesBtn">ADD CIRCLES</button>
这是我想出的,主要逻辑在函数 drawCircles() 中,在添加到矩形内之前检查圆是否重叠。需要注意的是程序在矩形内添加了100个圆圈
const canvas = new fabric.Canvas('gameCanvas', {selection: false});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
let rectangle;
const radius = 10;
let min_x;
let min_y;
let max_x;
let max_y;
let circles;
document.addEventListener('DOMContentLoaded', function(){
drawRectangle();
min_x = rectangle.left - rectangle.width / 2 ;
//min_x = 250 - 200/2;
max_x = rectangle.left + rectangle.width / 2;
//max_x = 250 + 200/2;
min_y = rectangle.top - rectangle.height / 2 ;
//min_y = 150 - 100/2;
max_y = rectangle.top + rectangle.height / 2;
//max_y = 150 + 100/2;
});
function drawRectangle()
{
rectangle = new fabric.Rect({
width: 200,
height: 100,
fill: 'blue',
opacity: 0.2,
left: 250,
top: 150
});
canvas.add(rectangle);
}
document.getElementById('addCirclesBtn').addEventListener('click', function(){
canvas.clear();
circles = [];
drawRectangle();
drawCircles();
});
function drawCircles()
{
let anti_crash_count = 0
while(circles.length < 100)
{
let circle = new fabric.Circle({
left: getRandomNumber(min_x + radius, max_x - radius),
top: getRandomNumber(min_y + radius, max_y - radius),
strokeWidth: 2,
radius: radius,
fill: 'white',
stroke: '#666',
selectable: false,
hoverCursor: 'default',
hasControls: false,
hasBorders: false,
originX:'center',
originY:'center'
});
let isOverlapping = false;
for(let j = 0; j < circles.length; j++)
{
let previous_circle = circles[j];
let distance = Math.hypot(circle.left - previous_circle.left, circle.top - previous_circle.top);
if(distance < (circle.radius + previous_circle.radius))
{
isOverlapping = true;
break;
}
}
if(!isOverlapping)
{
canvas.add(circle);
circles.push(circle);
}
anti_crash_count ++;
if(anti_crash_count > 1000)
{
break;
}
}
}
function getRandomNumber(min, max)
{
return Math.floor((Math.random() * (max - min)) + min);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.0.0/fabric.min.js"></script>
<canvas id="gameCanvas" width="500" height="300" style="border: 2px solid green;"></canvas>
<button id="addCirclesBtn">ADD CIRCLES</button>
如果有任何关于如何改进它的想法,我将不胜感激。
我正在尝试提出一种算法,在 fabricj canvas; 中添加 没有重叠的随机圆 下面的片段是我试过的。
const canvas = new fabric.Canvas('gameCanvas', {selection: false});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
let rectangle;
document.addEventListener('DOMContentLoaded', function(){
rectangle = new fabric.Rect({
width: 250,
height: 100,
fill: 'blue',
opacity: 0.2,
left: 200,
top: 140
});
canvas.add(rectangle);
});
document.getElementById('addCirclesBtn').addEventListener('click', function(){
drawCircles();
});
function drawCircles()
{
for(let i = 1; i <=20; i++)
{
let x= Math.random() * (rectangle.width - rectangle.left) + rectangle.left;
let y = Math.random() * (rectangle.height - rectangle.top) + rectangle.top;
let circle = new fabric.Circle({
left: x,
top: y,
strokeWidth: 2,
radius: 10,
fill: 'white',
stroke: '#666',
selectable: false,
hoverCursor: 'default',
hasControls: false,
hasBorders: false
});
canvas.add(circle);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.0.0/fabric.min.js"></script>
<canvas id="gameCanvas" width="500" height="300" style="border: 2px solid green;"></canvas>
<button id="addCirclesBtn">ADD CIRCLES</button>
这是我想出的,主要逻辑在函数 drawCircles() 中,在添加到矩形内之前检查圆是否重叠。需要注意的是程序在矩形内添加了100个圆圈
const canvas = new fabric.Canvas('gameCanvas', {selection: false});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
let rectangle;
const radius = 10;
let min_x;
let min_y;
let max_x;
let max_y;
let circles;
document.addEventListener('DOMContentLoaded', function(){
drawRectangle();
min_x = rectangle.left - rectangle.width / 2 ;
//min_x = 250 - 200/2;
max_x = rectangle.left + rectangle.width / 2;
//max_x = 250 + 200/2;
min_y = rectangle.top - rectangle.height / 2 ;
//min_y = 150 - 100/2;
max_y = rectangle.top + rectangle.height / 2;
//max_y = 150 + 100/2;
});
function drawRectangle()
{
rectangle = new fabric.Rect({
width: 200,
height: 100,
fill: 'blue',
opacity: 0.2,
left: 250,
top: 150
});
canvas.add(rectangle);
}
document.getElementById('addCirclesBtn').addEventListener('click', function(){
canvas.clear();
circles = [];
drawRectangle();
drawCircles();
});
function drawCircles()
{
let anti_crash_count = 0
while(circles.length < 100)
{
let circle = new fabric.Circle({
left: getRandomNumber(min_x + radius, max_x - radius),
top: getRandomNumber(min_y + radius, max_y - radius),
strokeWidth: 2,
radius: radius,
fill: 'white',
stroke: '#666',
selectable: false,
hoverCursor: 'default',
hasControls: false,
hasBorders: false,
originX:'center',
originY:'center'
});
let isOverlapping = false;
for(let j = 0; j < circles.length; j++)
{
let previous_circle = circles[j];
let distance = Math.hypot(circle.left - previous_circle.left, circle.top - previous_circle.top);
if(distance < (circle.radius + previous_circle.radius))
{
isOverlapping = true;
break;
}
}
if(!isOverlapping)
{
canvas.add(circle);
circles.push(circle);
}
anti_crash_count ++;
if(anti_crash_count > 1000)
{
break;
}
}
}
function getRandomNumber(min, max)
{
return Math.floor((Math.random() * (max - min)) + min);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.0.0/fabric.min.js"></script>
<canvas id="gameCanvas" width="500" height="300" style="border: 2px solid green;"></canvas>
<button id="addCirclesBtn">ADD CIRCLES</button>
如果有任何关于如何改进它的想法,我将不胜感激。