【问题标题】:Position circles around a circle given x circles with fixed diameter in SASS在 SASS 中给定 x 个具有固定直径的圆,围绕一个圆定位圆
【发布时间】:2019-09-11 06:44:19
【问题描述】:

两部分的问题:

最终目标是这样的,ala graph DB visualisers - 但在 html/css/sass

第 1 部分:如何围绕一个圆圈放置 x 个圆圈,以使边缘相互接触(或者最好带有一点空白)。 例如,这就是我要给定的 3、6 和 7 个圆圈。 我正在尝试使用 SASS 让它工作,但是如果有一个库或其他东西可以做我想做的事情,我宁愿使用它 - 我只是在努力制定搜索短语。

我用的是here的三角函数,偷了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;
  }

上面的代码主要是这样做的,但是与我的最终目标照片相比,间距没有优化,而且空白太多了。

【问题讨论】:

    标签: sass trigonometry


    【解决方案1】:

    距离需要在圆心 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;
    

    您将复制您当前正在执行的操作,从而导致圆圈重叠。

    ***** 已添加 *****

    由于圆的半径增大,第二、三、四级气泡的工作方式会随着您的扩展而变得有间隙。

    这样不行。

    我有一些东西但需要工作,但到目前为止我有这个......https://jsfiddle.net/hd7qp06b/2/

    我认为对于每一行,您都需要两组不同的公式才能使其完美运行,第二行有效,第三行无效,这是需要新公式的地方。会回到这个。

    这似乎有效:https://jsfiddle.net/eo170zsu/

    您必须跟踪一对相邻的气泡并在其旁边附加气泡。如果将气泡 9 和 15 的坐标放在堆栈上,它会将新气泡完美地放在它旁边。但是,您不能同时将气泡 9 和 16 放入堆栈,因为这会导致重叠。有一系列对是安全的,并且对于某些级别可能是一致的,我怀疑奇数/偶数级别有不同的配对规则。

    其实想想,9,15 和 9,16 对处理一个,如果屏幕上两个圆圈有重叠,就把它扔掉,再试试下一对。

    【讨论】:

    • 感谢您的回答,此解决方案将大红色圆圈半径作为输入,并计算出较小圆圈的半径。理想情况下,我只想定义较小圆圈的大小,并计算出与此相关的所有其他内容的位置……这可能吗?
    • 将最终输出缩放到您想要的大小 - 对之前的小提琴进行了微调 - 请参阅 jsfiddle.net/ptj192uf
    • 更改第一行以设置所需的圆半径。至于红圈,你可以删除所有对它的引用,包括变量。 var x = Math.cos(弧度) * redCircleRadius;会变成 var x = Math.cos(radians);红色圆圈仅供我参考,看看它是否有效
    • 使用你的回答和一些摆弄,我已经设法在 SASS 中实现你的建议,它就像你的 JS 版本一样工作(有轻微重叠的圆圈和所有)。 codepen.io/ollyboly/pen/BaBrPay
    • 这是一个添加了分层的版本(codepen.io/ollyboly/pen/aboYjrx)——我可能会在这个阶段放弃第 2 部分!感谢您的帮助
    猜你喜欢
    • 2019-04-14
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 2019-04-13
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多