我创建了一个Canvas动画,并设法将x个圆圈定位在圆形路径中。这是我使用的代码的简化版本:
var total = circles.length,
i = 0,
radius = 500,
angle = 0,
step = (2*Math.PI) / total;
for( i; i < total; i++ ) {
var circle = circles[i].children[0],
cRadius = circle[i].r,
x = Math.round(winWidth/2 + radius * Math.cos( angle ) - cRadius),
y = Math.round(winHeight/2 + radius * Math.sin( angle ) - cRadius);
circle.x = x;
circle.y = y;
angle += step;
}
结果如下:
我想要实现的是让所有圆圈彼此相邻,它们之间没有间隙(第一个和最后一个除外)。圆形尺寸(半径)是随机生成的,不应调整以适合圆形路径:
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
我预计第一个和最后一个圈之间会有差距。
我正在努力解决这个问题,所以任何帮助都会非常感激:)
干杯!
答案 0 :(得分:3)
主要创作循环:
•取当前半径
•计算它所覆盖的角度(= atan2(smallRadius / bigRadius))
•以最新角度移动底角。
http://jsfiddle.net/dj2v7mbw/9/
function CircledCircle(x, y, radius, margin, subCircleCount, subRadiusMin, subRadiusMax) {
this.x = x;
this.y = y;
this.radius = radius;
this.subCircleCount = subCircleCount;
var circles = this.circles = [];
// build top sub-circles
var halfCount = Math.floor(subCircleCount / 2);
var totalAngle = addCircles(halfCount);
// re-center top circles
var correction = totalAngle / 2 + Math.PI / 2;
for (var i = 0; i < halfCount; i++) this.circles[i].angle -= correction;
// build bottom sub-circles
totalAngle = addCircles(subCircleCount - halfCount);
// re-center bottom circles
var correction = totalAngle / 2 - Math.PI / 2;
for (var i = halfCount; i < subCircleCount; i++) this.circles[i].angle -= correction;
// -- draw this C
this.draw = function (angleShift) {
for (var i = 0; i < this.circles.length; i++) drawDistantCircle(this.circles[i], angleShift);
}
//
function drawDistantCircle(c, angleShift) {
angleShift = angleShift || 0;
var thisX = x + radius * Math.cos(c.angle + angleShift);
var thisY = y + radius * Math.sin(c.angle + angleShift);
ctx.beginPath();
ctx.arc(thisX, thisY, c.r, 0, 2 * Math.PI);
ctx.fillStyle = 'hsl(' + (c.index * 15) + ',75%, 75%)';
ctx.fill();
ctx.stroke();
}
//
function addCircles(cnt) {
var currAngle = 0;
for (var i = 0; i < cnt; i++) {
var thisRadius = getRandomInt(subRadiusMin, subRadiusMax);
var thisAngle = Math.atan2(2 * thisRadius + margin, radius);
var thisCircle = new subCircle(thisRadius, currAngle + thisAngle / 2, i);
currAngle += thisAngle;
circles.push(thisCircle);
}
return currAngle;
}
}
带
function subCircle(radius, angle, index) {
this.r = radius;
this.angle = angle;
this.index = index;
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
与
一起使用 var myCircles = new CircledCircle(winWidth / 2, winHeight / 2, 350, 2, 24, 5, 50);
myCircles.draw();
动画:
var angleShift = 0;
function draw() {
requestAnimationFrame(draw);
ctx.clearRect(0, 0, winWidth, winHeight);
myCircles.draw(angleShift);
angleShift += 0.010;
}
draw();
答案 1 :(得分:2)
这是这样的,但你必须弄清楚最后一个圆圈的大小:
http://jsfiddle.net/rudiedirkx/ufvf62yf/2/
主要逻辑:
var firstStep = 0, rad = 0, step = 0;
firstStep = step = stepSize();
for ( var i=0; i<30; i++ ) {
draw.radCircle(rad, step);
rad += step;
step = stepSize();
rad += step;
}
stepSize()
在Math.PI/48
和Math.PI/48 + Math.PI/36
之间创建一个随机rad(没有特殊原因,但看起来不错)。您可以将其修复为正确的尺寸。draw.radCircle(rad, step)
在尺寸为rad
的位置step
处创建一个圆圈(也是以rad为单位)。step
每次迭代添加两次:一次从当前圆圈的中心步进到边缘,一次找到下一个圆圈的中心firstStep
很重要,因为你必须知道在哪里停止绘图(因为第一个圆圈交叉成负角度) draw.radCircle()
中还有一些魔力:
var r = rRad * Math.PI/3 * 200 * .95;
200
显然是大圆的半径95%
是因为圆的边长略长于每个圆的(直)半径Math.PI/3
是......我认为它必须是Math.PI / 2,这是1 rad,但这根本不起作用。 1/3
由于某种原因确实.....解释!如果您想要设置这些圆圈大小的动画并保持它们对齐,那么您将会遇到困难。他们现在都是随机的。在动画中,只有第一次迭代可以是随机的,其余的是一大堆缓存和数学=)