SVG CSS过渡转换在Firefox中闪烁

时间:2020-05-12 21:25:21

标签: javascript html css svg

我有一个带有图标的按钮,它是嵌入式svg元素。当我单击该图标时,css将应用三个转换。

  1. 白色svg圆圈转化为主要的黑色圆圈以使其重叠。
  2. 容纳两个圆圈的g容器被放大。
  3. 同时容纳两个圆的g容器旋转了30度。

在Firefox过渡结束时,一旦圆圈重叠,就会闪烁。

很难调试,因为当我打开firefox devtools时,闪烁很少发生。

const btnToggle = document.querySelector(".btn-toggle");
const moonShadow = document.querySelector(".moon-shadow");
const sunAndMoon = document.querySelector(".sun-and-moon");

let toggle = true;
btnToggle.addEventListener("click", () => {
  if (toggle) {
    moonShadow.style.transform = "translateX(0px)";
    sunAndMoon.style.transform = "scale(1.5) rotate(30deg)";
  } else {
    moonShadow.style.transform = "translateX(-15px)";
    sunAndMoon.style.transform = "scale(1) rotate(0deg)";
  }
  toggle = !toggle;
});
main {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}

.btn-toggle {
  border: 0;
  background: inherit;
  cursor: pointer;
}

/* svg classes */
.sun-and-moon {
  transform-origin: center;
  transition: transform 450ms;
}
.moon-shadow {
  transform-origin: center;
  -webkit-transform: translateZ(0);
  transition: transform 550ms;
}
 
<main>
   <p>Click icon</p>
    <button class="btn-toggle">
      <svg xmlns="http://www.w3.org/2000/svg" width="84.0661" height="84.0661" viewBox="0 0 22.2425 22.2425">
        <g class="sun-and-moon">
          <circle class="sun" r="4.4093" cy="11.1212" cx="11.1212" fill="currentColor" />
          <circle class="moon-shadow" style="transform: translateX(-15px);" r="4.4093" cy="11.1212" cx="7.5566"
            fill="#fff" />
        </g>
      </svg>
    </button>
  </main>

1 个答案:

答案 0 :(得分:2)

我已经对您的代码进行了一些微调以使其正常工作,并且还删除了JavaScript设置的内联CSS,因为如果不需要的话,我不建议这样做。 ;)

真正“解决”问题的是:

backface-visibility: hidden;

https://www.w3schools.com/CSSref/css3_pr_backface-visibility.asp

代码示例 https://jsfiddle.net/Dave/k0q4m5jr/

HTML

<main>
   <p>Click icon</p>
    <button class="btn-toggle">
      <svg xmlns="http://www.w3.org/2000/svg" width="84.0661" height="84.0661" viewBox="0 0 22.2425 22.2425">
        <g class="sun-and-moon">
          <circle class="sun" r="4.4093" cy="11.1212" cx="11.1212" fill="currentColor" />
          <circle class="moon-shadow" r="4.4093" cy="11.1212" cx="7.5566"
            fill="#fff" />
        </g>
      </svg>
    </button>
  </main>

CSS

main {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}

.btn-toggle {
  border: 0;
  background: inherit;
  cursor: pointer;
}

/* svg classes */
.sun-and-moon {
  backface-visibility: hidden; /* Prevents flickering */
  transform-origin: center;
  transition: transform 450ms;
  transform: scale(1) rotate(0deg);

   /* Added, to prevent inline CSS when not needed. */
  .is-active & {
    transform: scale(1.5) rotate(30deg);
  }
}
.moon-shadow {
  backface-visibility: hidden;  /* Prevents flickering */
  transform-origin: center;
  transform: translateZ(0) translateX(-15px);
  transition: transform 550ms;

   /* Added, to prevent inline CSS when not needed. */
  .is-active & {
    transform: translateX(0px);
  }
}

JavaScript

const btnToggle = document.querySelector(".btn-toggle");
const moonShadow = document.querySelector(".moon-shadow");
const sunAndMoon = document.querySelector(".sun-and-moon");
const activeClass = 'is-active';

btnToggle.addEventListener("click", (event) => {
  let isActive = event.currentTarget.classList.contains(activeClass);

  if (!isActive) {
    btnToggle.classList.add(activeClass);
  } else {
    btnToggle.classList.remove(activeClass);
  }
});