在 SASS 中给定 x 个具有固定直径的圆,围绕一个圆定位圆
Position circles around a circle given x circles with fixed diameter in SASS
两部分的问题:
最终目标是这样的,ala graph DB visualisers - 但在 html / css/sass
第 1 部分:如何在一个圆周围放置 x 个圆,使边缘接触(或者最好有一点空白)。
例如,这就是我要给定的 3、6 和 7 个圆圈。
我正在尝试使用 SASS 使其正常工作,但是如果有图书馆或其他东西可以满足我的需求,我宁愿使用它 - 我只是在努力制定搜索短语。
我正在使用 here, and stole the circle arrangement from here 中的三角函数。
CODEPEN 到目前为止我得到的。
我的数学不好,但一些朋友给了我一个公式,您可以在下面找到该公式,可以计算出到外圆中心的距离。 $distance: tan((180-($angle))/2) * $radius;
。然而它并不像我预期的那样 - 给定 6 个圆圈,直径为 100 我希望输出为 100,但我得到 86.602...
这是 sass - 不过在 codepen 中可能更容易查看。
@function strip-unit($number) {
@if type-of($number) == 'number' and not unitless($number) {
@return $number / ($number * 0 + 1);
}
@return $number;
}
@mixin on-circle($item-count, $circle-size, $item-size, $break-at) {
position: relative;
height: $circle-size;
padding: 0;
border-radius: 50%;
list-style: none;
>* {
display: block;
position: absolute;
top: 50%;
left: 50%;
width: $item-size;
height: $item-size;
margin: -($item-size / 2);
$angle: (360 / $break-at);
$rot: 0;
$prevLayer: 0;
@for $i from 1 through $item-count {
$layer: ceil($i/ $break-at);
$layerMinusOne: $layer - 1;
// MoveX figured out by aligning stuff by eye
// item-count 3 4 5 6 7 8 9 10 ...12 13 14...20
// moveX (%) 57 70 85 100 115 130 145 160 192 207 225 315
$item-radius: strip-unit($item-size) / 2;
// !! This is where i'm having trouble
$distance: tan((180-($angle * 1deg))/2) * $item-radius;
@debug "tan((180-#{$angle})/2) * #{$item-radius} = #{$distance}";
$moveX: ( $distance / strip-unit($item-size)) * 100 * 1%;
@debug "moveX: #{$moveX}";
@if $layer != $prevLayer {
$prevLayer: $layer;
$rot: $rot + $angle/2;
}
&:nth-of-type(#{$i}) {
transform:
// !! This is where the 'percent of circle diameter' measurements come in, translateX uses the size of the element being transformed when % is used.
rotate($rot * 1deg) translateX($moveX * $layer) rotate($rot * -1deg);
}
$rot: $rot+$angle;
}
}
}
$numOfCircles: 3; // <- Change me in the codepen
.circle-container {
@include on-circle($item-count: 28, $circle-size: 200px, $item-size: 50px,
$break-at: $numOfCircles);
margin: 5em auto 5em;
border: solid 5px red;
.around-a-circle {
text-align: center;
border-radius: 50%;
border: solid 1px #118be1;
}
}
第 2 部分:额外的图层。
如上所示,我的最终目标是在环中显示 x 个圆形元素,其中最里面的环由 y 个元素组成,并从那里冒泡。
正如我所说,我宁愿使用图书馆,但我找不到任何我想要的东西。我打算使用内环作为起点和每个交替层,旋转额外一点并将元素放在前面的环元素之间,但我再次在尺寸和偏移量方面苦苦挣扎。
$layer: ceil($i/ $break-at);
...
@if $layer != $prevLayer {
$prevLayer: $layer;
$rot: $rot + $angle/2;
}
上面的代码大部分都是这样做的,但是间距没有优化,而且与我的最终目标照片相比,空白太多了。
圆心 1 和圆心 2 之间的距离必须是所有圆的半径的一半。
我不知道 sass 所以这里有一个有效的 JS 版本来证明它有效。
https://jsfiddle.net/hk5spy20/
如果您将第 32-33 行从
var x1 = pointXY[0].x;
var y1 = pointXY[0].y;
到
var x1 = xPos;
var y1 = yPos;
你将复制你当前正在做的事情,这会导致重叠的圆圈。
***** 添加了 *****
当你向外扩展时,第 2、3、4 级气泡的工作方式会变得有间隙,因为圆的半径会增加。
这样不行。
我有一些东西但需要工作,但到目前为止我有这个... https://jsfiddle.net/hd7qp06b/2/
我认为对于每一行,您将需要两组不同的公式才能使其完美运行,第二行有效,第三行无效,这是需要新公式的地方。会回来的。
这似乎有效:https://jsfiddle.net/eo170zsu/
您必须跟踪相邻的一对泡泡并将泡泡附加到它旁边。如果你把气泡 9 和 15 的坐标放在堆栈上,它会在它旁边放置新的气泡。但是,您不能将气泡 9 和气泡 16 也放在堆栈上,因为这会导致重叠。有一系列对是安全的,并且可能在某些级别上是一致的,我怀疑奇数/偶数级别有不同的配对规则。
实际上,考虑一下,只需对 9,15 和 9,16 进行处理,如果屏幕上两个圆圈之间有重叠,则将其丢弃并尝试下一对。
两部分的问题:
最终目标是这样的,ala graph DB visualisers - 但在 html / css/sass
第 1 部分:如何在一个圆周围放置 x 个圆,使边缘接触(或者最好有一点空白)。 例如,这就是我要给定的 3、6 和 7 个圆圈。 我正在尝试使用 SASS 使其正常工作,但是如果有图书馆或其他东西可以满足我的需求,我宁愿使用它 - 我只是在努力制定搜索短语。
我正在使用 here, and stole the circle arrangement from here 中的三角函数。
CODEPEN 到目前为止我得到的。
我的数学不好,但一些朋友给了我一个公式,您可以在下面找到该公式,可以计算出到外圆中心的距离。 $distance: tan((180-($angle))/2) * $radius;
。然而它并不像我预期的那样 - 给定 6 个圆圈,直径为 100 我希望输出为 100,但我得到 86.602...
这是 sass - 不过在 codepen 中可能更容易查看。
@function strip-unit($number) {
@if type-of($number) == 'number' and not unitless($number) {
@return $number / ($number * 0 + 1);
}
@return $number;
}
@mixin on-circle($item-count, $circle-size, $item-size, $break-at) {
position: relative;
height: $circle-size;
padding: 0;
border-radius: 50%;
list-style: none;
>* {
display: block;
position: absolute;
top: 50%;
left: 50%;
width: $item-size;
height: $item-size;
margin: -($item-size / 2);
$angle: (360 / $break-at);
$rot: 0;
$prevLayer: 0;
@for $i from 1 through $item-count {
$layer: ceil($i/ $break-at);
$layerMinusOne: $layer - 1;
// MoveX figured out by aligning stuff by eye
// item-count 3 4 5 6 7 8 9 10 ...12 13 14...20
// moveX (%) 57 70 85 100 115 130 145 160 192 207 225 315
$item-radius: strip-unit($item-size) / 2;
// !! This is where i'm having trouble
$distance: tan((180-($angle * 1deg))/2) * $item-radius;
@debug "tan((180-#{$angle})/2) * #{$item-radius} = #{$distance}";
$moveX: ( $distance / strip-unit($item-size)) * 100 * 1%;
@debug "moveX: #{$moveX}";
@if $layer != $prevLayer {
$prevLayer: $layer;
$rot: $rot + $angle/2;
}
&:nth-of-type(#{$i}) {
transform:
// !! This is where the 'percent of circle diameter' measurements come in, translateX uses the size of the element being transformed when % is used.
rotate($rot * 1deg) translateX($moveX * $layer) rotate($rot * -1deg);
}
$rot: $rot+$angle;
}
}
}
$numOfCircles: 3; // <- Change me in the codepen
.circle-container {
@include on-circle($item-count: 28, $circle-size: 200px, $item-size: 50px,
$break-at: $numOfCircles);
margin: 5em auto 5em;
border: solid 5px red;
.around-a-circle {
text-align: center;
border-radius: 50%;
border: solid 1px #118be1;
}
}
第 2 部分:额外的图层。
如上所示,我的最终目标是在环中显示 x 个圆形元素,其中最里面的环由 y 个元素组成,并从那里冒泡。
正如我所说,我宁愿使用图书馆,但我找不到任何我想要的东西。我打算使用内环作为起点和每个交替层,旋转额外一点并将元素放在前面的环元素之间,但我再次在尺寸和偏移量方面苦苦挣扎。
$layer: ceil($i/ $break-at);
...
@if $layer != $prevLayer {
$prevLayer: $layer;
$rot: $rot + $angle/2;
}
上面的代码大部分都是这样做的,但是间距没有优化,而且与我的最终目标照片相比,空白太多了。
圆心 1 和圆心 2 之间的距离必须是所有圆的半径的一半。
我不知道 sass 所以这里有一个有效的 JS 版本来证明它有效。
https://jsfiddle.net/hk5spy20/
如果您将第 32-33 行从
var x1 = pointXY[0].x;
var y1 = pointXY[0].y;
到
var x1 = xPos;
var y1 = yPos;
你将复制你当前正在做的事情,这会导致重叠的圆圈。
***** 添加了 *****
当你向外扩展时,第 2、3、4 级气泡的工作方式会变得有间隙,因为圆的半径会增加。
这样不行。
我有一些东西但需要工作,但到目前为止我有这个... https://jsfiddle.net/hd7qp06b/2/
我认为对于每一行,您将需要两组不同的公式才能使其完美运行,第二行有效,第三行无效,这是需要新公式的地方。会回来的。
这似乎有效:https://jsfiddle.net/eo170zsu/
您必须跟踪相邻的一对泡泡并将泡泡附加到它旁边。如果你把气泡 9 和 15 的坐标放在堆栈上,它会在它旁边放置新的气泡。但是,您不能将气泡 9 和气泡 16 也放在堆栈上,因为这会导致重叠。有一系列对是安全的,并且可能在某些级别上是一致的,我怀疑奇数/偶数级别有不同的配对规则。
实际上,考虑一下,只需对 9,15 和 9,16 进行处理,如果屏幕上两个圆圈之间有重叠,则将其丢弃并尝试下一对。