javascript - 使用translate3d和scale进行转换

标签 javascript html css css-animations translate3d

我想制作一个跟随光标并同时以动画形式增大/缩小的 div
我使用 topleft 更改了 div 的位置,但动画有时有点不稳定。

我想使用translate3d来制作animations smooth ,但我正在努力将 translate3dscale

结合起来
const moveCursor = event => {
    const cursorWidth = cursor.offsetWidth / 2;
    cursor.style.left = event.pageX - cursorWidth + "px";
    cursor.style.top = event.pageY - cursorWidth + "px";
};  

我想修改此函数以使用 translate3d 而不是 topleft 并保留现有的 scale动画中的变换值

我想出了这个,但它不起作用

const moveCursor = event => {
    const cursorWidth = cursor.offsetWidth / 2;
    const xCoordinate = event.pageX - cursorWidth + "px";
    const yCoordinate = event.pageY - cursorWidth + "px";

    const matrix = window.getComputedStyle(cursor).transform;
    const scalingFactor = parseFloat(matrix.split(",")[3]);

    cursor.style.transform = `translate3d(${xCoordinate},${yCoordinate},0px) scale(${scalingFactor})`
};

我哪里出错了?

const cursor = document.getElementById("cursor");
const moveCursor = event => {
  const cursorWidth = cursor.offsetWidth / 2;
  cursor.style.left = event.pageX - cursorWidth + "px";
  cursor.style.top = event.pageY - cursorWidth + "px";
};
document.addEventListener("mousemove", moveCursor);
#background {
  position: relative;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  background-color: #0e0e0e;
  color: ivory;
  font-size: 3rem;
  text-align: center;
}

#cursor {
  width: 15rem;
  height: 15rem;
  will-change: transform;
  background: ivory;
  position: absolute;
  mix-blend-mode: difference;
  border-radius: 50%;
  animation: grow-shrink 4s infinite alternate;
}

@keyframes grow-shrink {
  0% {
    transform: scale(1.2);
  }
  25% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1.2);
  }
  75% {
    transform: scale(0.8);
  }
  100% {
    transform: scale(1);
  }
}
<div id="background">
  Lorem Ipsum
  <div id="cursor"></div>
</div>

最佳答案

动画将覆盖您使用elem.style设置的值。
为了避免这种情况,您可以添加一个仅用于翻译的包装元素,并将缩放动画保留在包装元素上,或者您应该能够使用 css 变量来更新动画中的翻译值,但 Chrome 不会更新动画我不知道什么原因:

此代码段仅适用于 Firefox

const cursor = document.getElementById("cursor");
const moveCursor = event => {
  const cursorWidth = cursor.offsetWidth / 2;
  cursor.style.setProperty( '--translate-x', event.pageX - cursorWidth + "px" );
  cursor.style.setProperty( '--translate-y', event.pageY - cursorWidth + "px" );
;}
document.addEventListener("mousemove", moveCursor);
#background {
  position: relative;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  background-color: #0e0e0e;
  color: ivory;
  font-size: 3rem;
  text-align: center;
}

#cursor {
  width: 15rem;
  height: 15rem;
  will-change: transform;
  background: ivory;
  position: absolute;
  mix-blend-mode: difference;
  border-radius: 50%;
  animation: grow-shrink 4s infinite alternate;
  --translate-x: 0px;
  --translate-y: 0px;
  --translate: translate( var(--translate-x), var(--translate-y) );
}

@keyframes grow-shrink {
  0% {
    transform: var(--translate) scale(1.2);
  }
  25% {
    transform: var(--translate) scale(0.8);
  }
  50% {
    transform: var(--translate) scale(1.2);
  }
  75% {
    transform: var(--translate) scale(0.8);
  }
  100% {
    transform: var(--translate) scale(1);
  }
}
<div id="background">
  Lorem Ipsum
  <div id="cursor"></div>
</div>

所以这给我们留下了包装器解决方案:

const cursor = document.getElementById("trans-wrapper");
const moveCursor = event => {
  const cursorWidth = cursor.offsetWidth / 2;
  cursor.style.left = event.pageX - cursorWidth + "px";
  cursor.style.top = event.pageY - cursorWidth + "px";
};
document.addEventListener("mousemove", moveCursor);
#background {
  position: relative;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  background-color: #0e0e0e;
  color: ivory;
  font-size: 3rem;
  text-align: center;
}

#cursor {
  width: 15rem;
  height: 15rem;
  will-change: transform;
  background: ivory;
  border-radius: 50%;
  animation: grow-shrink 4s infinite alternate;
}
#trans-wrapper {
  width: 15rem;
  height: 15rem;
  will-change: transform;
  position: absolute;
  mix-blend-mode: difference;  
}


@keyframes grow-shrink {
  0% {
    transform: scale(1.2);
  }
  25% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1.2);
  }
  75% {
    transform: scale(0.8);
  }
  100% {
    transform: scale(1);
  }
}
<div id="background">
  Lorem Ipsum
  <div id="trans-wrapper">
    <div id="cursor"></div>
  </div>
</div>

关于javascript - 使用translate3d和scale进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63108545/

相关文章:

html - 无法正确显示 HTML 表格和颜色

css - 标签文本未环绕在 Bootstrap 网格设置中

Javascript递归导致循环结构

javascript - 取消设置元素可见性,更改 innerHTML,然后过渡回来

html - 特定元素在 IE 和 Chrome 中正确定位,但在 Firefox 中不正确......我不明白为什么?

html - 在图像上定位超链接

javascript - Angular 。删除根标签上的属性

javascript - 如何在 Node.js 中使用 Promise 编写带参数的函数?

css - 在 Angular 6 中更改侧边栏选定值的颜色

html - 是什么导致这些按钮出现这种神秘的垂直偏移?