如何使用 css 调整旋转半径

How to resize rotation radius using css

如何调整球的旋转半径,使其接触橙色容器边框

.bg {
    background-color: blue;

    display: flex;
    align-items: center;
    justify-content: center;
}

.ball-container {
    position: relative;
    display:flex;
    justify-content:center;
    align-items:center;
    background-color: orange;
    width: 250px;
    height: 250px;
}

.ball {
    position: absolute;
    width: 24px;
    height: 24px;
    background-color: white;
    border-radius: 50%;

    top: 125px - 12px;
    left: 125px - 12px;

    animation-name: ball_moves;
    animation-duration: 1.5s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: initial;
}

.ball:nth-child(1) {
    transform-origin: top left;
}
.ball:nth-child(2) {
    transform-origin: top right;
}
.ball:nth-child(3) {
    transform-origin: bottom left;
}
.ball:nth-child(4) {
    transform-origin: bottom right;
}

@keyframes ball_moves {
    0% {
        transform: rotateZ(0);
    }
    100% {
        transform: rotateZ(360deg);
    }
}
<div class="bg">

    <div class="ball-container">
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
    </div>

</div>

使用 CSS 变量来定义一个唯一的偏移量,可以使用 transform-origin 控制你所有的圆:

.bg {
    background-color: blue;

    display: flex;
    align-items: center;
    justify-content: center;
    margin:10px;
}

.ball-container {
    --d:35px; /* adjust this like you want (you can even use % value)*/
    /* 
      1) we first find the middle of each small square
        the size is 250/2=125 so we translate by (125-24)/2 = 50.5px
        this will put the origin in the middle and give us a rotation 
        following the "circumscribe" circle so we the circle will go outside
      2) we need to decrease it to keep the rotation inside
         the calculate is a bit complex but we decrease by around 15px to have 35px
    */
    
    position: relative;
    display:flex;
    justify-content:center;
    align-items:center;
    background: 
      linear-gradient(red,red) center/100% 1px,
      linear-gradient(red,red) center/1px 100%,
      orange;
    background-repeat:no-repeat;
    width: 250px;
    height: 250px;
}

.ball {
    position: absolute;
    width: 24px;
    height: 24px;
    background-color: white;
    border-radius: 50%;

    animation-name: ball_moves;
    animation-duration: 1.5s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: initial;
}

.ball:nth-child(1) {
    transform-origin: calc(-1*var(--d)) calc(-1*var(--d));
}
.ball:nth-child(2) {
    transform-origin: calc(-1*var(--d)) calc(100% + var(--d));
}
.ball:nth-child(3) {
    transform-origin: calc(100% + var(--d)) calc(-1*var(--d));
}
.ball:nth-child(4) {
    transform-origin: calc(100% + var(--d)) calc(100% + var(--d));
}

@keyframes ball_moves {
    0% {
        transform: rotateZ(0);
    }
    100% {
        transform: rotateZ(360deg);
    }
}
<div class="bg">

    <div class="ball-container">
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
    </div>

</div>

<div class="bg">

    <div class="ball-container" style="--d:100%;"> <!-- 100% = 24px (size of circle) -->
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
    </div>

</div>

使用另一种语法:

.bg {
    background-color: blue;

    display: flex;
    align-items: center;
    justify-content: center;
    margin:10px;
}

.ball-container {
    --d:47px; /* adjust this like you want (you can even use % value)*/
    /* 
      1) we first find the middle of each small square
        the size is 250/2=125 so we translate by (125)/2 = 66.5px
        this will put the origin in the middle and give us a rotation 
        following the "circumscribe" circle so we the circle will go outside
      2) we need to decrease it to keep the rotation inside
         the calculate is a bit complex but we decrease by around 15px to have 47px
    */
    
    position: relative;
    display:flex;
    justify-content:center;
    align-items:center;
    background: 
      linear-gradient(red,red) center/100% 1px,
      linear-gradient(red,red) center/1px 100%,
      orange;
    background-repeat:no-repeat;
    width: 250px;
    height: 250px;
}

.ball {
    position: absolute;
    width: 24px;
    height: 24px;
    background-color: white;
    border-radius: 50%;

    animation-name: ball_moves;
    animation-duration: 1.5s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: initial;
}

.ball:nth-child(1) {
    transform-origin: calc(50% - var(--d)) calc(50% - var(--d));
}
.ball:nth-child(2) {
    transform-origin: calc(50% - var(--d)) calc(50% + var(--d));
}
.ball:nth-child(3) {
    transform-origin: calc(50% + var(--d)) calc(50% - var(--d));
}
.ball:nth-child(4) {
    transform-origin: calc(50% + var(--d)) calc(50% + var(--d));
}

@keyframes ball_moves {
    0% {
        transform: rotateZ(0);
    }
    100% {
        transform: rotateZ(360deg);
    }
}
<div class="bg">

    <div class="ball-container">
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
    </div>

</div>

<div class="bg">

    <div class="ball-container" style="--d:200%;"> <!-- 100% = 48px (size of circle) -->
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
        <div class="ball"></div>
    </div>

</div>