如何使用 CSS 自定义属性和变换每 3 秒将 4 children 在一个圆内旋转 90 度?

How to rotate 4 children within a circle 90 degrees every 3 seconds using CSS custom properties and transform?

我尝试使用名为 [=16] 的 CSS 自定义 属性 将圆内的 4 children (.feat) 个元素每 3 秒旋转 90 度=],但它似乎没有按预期工作:

function rotation() {
  let inner = document.querySelector('[inn]');
  let rota = inner.style.transform;
}

setInterval(rotation, 3000);
.feat-cont {
  width: 60vmax;
  height: 60vmax;
}

.feat-cont p {
  display: inline-block;
}

.inner {
  --angle: 0;
  
  position: relative;
  background-color: yellow;
  transform: rotate(var(--angle) * 1deg);
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

.feat {
  position: absolute;
}

.feat1 {
  left: 25vmax;
}

.feat2 {
  left: 50vmax;
  top: 25vmax;
}

.feat3 {
  left: 25vmax;
  top: 50vmax;
}

.feat4 {
  top: 25vmax;
}
<div class='feat-cont'>
  <div class='inner' inn>
    <div class='feat feat1' f1>
      <img src="https://img.icons8.com/nolan/64/fast-forward.png"/>
      <p>Fast Performance</p>
    </div>

    <div class='feat feat2' f2>
      <img src="https://img.icons8.com/color/48/000000/memory-slot.png"/>
      <p>64 GBs of memory</p>
    </div>

    <div class='feat feat3' f3>
      <img src="https://img.icons8.com/nolan/64/camera.png"/>
      <p>3K MP camera</p>
    </div>

    <div class='feat feat4' f4>
      <img src="https://img.icons8.com/dusk/64/000000/branding.png"/>
      <p>Trusted brand</p>
    </div>
  </div>
</div>

更新您的 javascript 代码

setInterval(rotation, 3000);
var deg = 90;
let inner = document.querySelector('.inner');

function rotation() {
 inner.style.transform='rotate('+deg+'deg)'; 
}

您可以更改 angle CSS custom property using CSSStyleDeclaration.setProperty():

circle.style.setProperty('--angle', `${ angle }deg`);

此外,请注意您将它用作 transform: rotate(var(--angle)),而不是 rotate(var(--angle) * 1deg),因此该单位应该已经包含在 CSS 属性.[=23= 中]

如果不想使用CSS属性,可以直接更改style属性:

circle.style.transform = `rotate(${ angle }deg)`;

但是,我想你需要在一个方向上旋转圆,同时在相反的方向上旋转所有 children (.feat) 以保持它们的直线,所以使用 CSS properties 可能更方便,否则,您将不得不更改所有 4 children:

中的 style 属性

const circle = document.querySelector('.circle');
const prev = document.querySelector('.prev');
const next = document.querySelector('.next');
const step = 90;

let angle = 0;
let intervalID = null;

function updateRotation() {
  circle.style.setProperty('--angle', `${ angle }deg`);
  circle.style.setProperty('--angle-inverse', `${ -angle }deg`);
}

function autoRotate() {
  intervalID = setInterval(() => {
    angle += step;  
    updateRotation();
  }, 3000);
}

prev.onclick = () => {
  clearInterval(intervalID);
  angle -= step;
  updateRotation();
  autoRotate();
};

next.onclick = () => {
  clearInterval(intervalID);
  angle += step;
  updateRotation();
  autoRotate();
};

autoRotate();
body {
  font-family: monospace;
}

.container {
  width: 60vmax;
  height: 60vmax;
  margin: 0 auto;
  overflow: hidden;
}

.circle {
  --angle: 0;
  --angle-inverse: 0;
  
  position: relative;
  background-color: yellow;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  transition: transform linear 1s;
  transform: rotate(var(--angle));
}

.feat {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 20vmax;
  height: 20vmax;
  text-align: center;
  transition: transform linear 1s;
}

.feat > img {
  width: 10vmax;
  height: 10vmax;
}

.feat > p {
  margin: 8px 0 0;
}

.feat1 {
  top: 0;
  left: 50%;
  transform: translate(-50%, 0) rotate(var(--angle-inverse));
}

.feat2 {
  right: 0;
  top: 50%;
  transform: translate(0, -50%) rotate(var(--angle-inverse));
}

.feat3 {
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 0) rotate(var(--angle-inverse));
}

.feat4 {
  left: 0;
  top: 50%;
  transform: translate(0, -50%) rotate(var(--angle-inverse));
}

.button {
  position: fixed;
  top: 0;
  bottom: 0;
  background: transparent;
  border: 0;
  padding: 32px;
  outline: none;
  font-family: monospace;
  font-size: 32px;
}

.button:hover {
  background: rgba(0, 0, 0, .0625);
}

.prev {
  left: 0;
}

.next {
  right: 0;
}
<div class="container">
  <button class="button prev">‹</button>
  
  <div class="circle">
    <div class="feat feat1">
      <img src="https://img.icons8.com/nolan/64/fast-forward.png"/>
      <p>Fast Performance</p>
    </div>

    <div class="feat feat2">
      <img src="https://img.icons8.com/color/48/000000/memory-slot.png"/>
      <p>64 GBs of memory</p>
    </div>

    <div class="feat feat3">
      <img src="https://img.icons8.com/nolan/64/camera.png"/>
      <p>3K MP camera</p>
    </div>

    <div class="feat feat4">
      <img src="https://img.icons8.com/dusk/64/000000/branding.png"/>
      <p>Trusted brand</p>
    </div>
  </div>
  
  <button class="button next">›</button>
</div>

我添加了一个纯 CSS 解决方案,您可能根本不需要 javascript 操作,它也很轻量级。 只需使用 CSS 内置 Animation 属性.

.inner{animation: rotate 12s infinite;}

@keyframes rotate{
  0%{transform: rotate(0deg);}
  25%{transform: rotate(90deg);}
  50%{transform: rotate(180deg);}
  75%{transform: rotate(270deg);}
  100%{transform: rotate(360deg);}
}

找到代码笔here

.feat-cont {
  width: 60vmax;
  height: 60vmax;
}

.feat-cont p {
  display: inline-block;
}

.inner {
  position: relative;
  background-color: yellow;
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

.feat {
  position: absolute;
}

.feat1 {
  left: 25vmax;
}

.feat2 {
  left: 50vmax;
  top: 25vmax;
}

.feat3 {
  left: 25vmax;
  top: 50vmax;
}

.feat4 {
  top: 25vmax;
}

.inner {
  animation: rotate 12s infinite;
}

@keyframes rotate{
0%{transform: rotate(0deg);}
  25%{transform: rotate(90deg);}
  50%{transform: rotate(180deg);}
  75%{transform: rotate(270deg);}
  100%{transform: rotate(360deg);}
}

@keyframes r-rotate{
0%{transform: rotate(0deg);}
  25%{transform: rotate(-90deg);}
  50%{transform: rotate(-180deg);}
  75%{transform: rotate(-270deg);}
  100%{transform: rotate(-360deg);}
}

.feat {
  animation: r-rotate 12s infinite;
}
<nav></nav>

<main>
  <section>
  <div class='feat-cont'>
    <div class='inner' inn>
      
    <div class='feat feat1' f1>
      <img src="https://img.icons8.com/nolan/64/fast-forward.png"/><br><p>Fast Performance</p>
    </div>
    
    <div class='feat feat2' f2>
      <img src="https://img.icons8.com/color/48/000000/memory-slot.png"/><br><p>64 GBs of memory</p>
    </div>
    
    <div class='feat feat3' f3>
    <img src="https://img.icons8.com/nolan/64/camera.png"/><br><p>3K MP camera</p>
    </div>
    
    <div class='feat feat4' f4>
    <img src="https://img.icons8.com/dusk/64/000000/branding.png"/><br><p>Trusted brand</p>
    </div>
    
  </div>
  </div>
  </section>
  <section class='ndsection'>
</main>