使用translate3d和scale进行转换 [英] Using translate3d and scale for transformations

查看:160
本文介绍了使用translate3d和scale进行转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作一个 div ,使其跟随光标,并同时随着动画的增长/缩小.
我使用 top left 更改了 div 的位置,但动画有时有点断断续续.

I wanted to make a div that follows the cursor and simultaneously grows/shrinks as an animation.
I changed the position of the div using top and left but the animation is sometimes a bit choppy.

我想使用 translate3d 使动画流畅,但我正在努力将 translate3d scale

I wanted to use translate3d to make the animations smooth, but I'm struggling to combine translate3d with scale

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

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

I wanted to modify this function to use translate3d instead of top and left and keep the existing scale transformation values from the animation

我想到了这一点,但是它不起作用

I came up with this, but it isn't working

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不会更新动画,因为我不知道是什么原因:

The animation will override the values you set with elem.style.
To circumvent this you could add a wrapper element only for translation and keep the scale animation on the wrapped element, or you should have been able to use css-variables to update the translation values in the animation, except that Chrome doesn't update the animation for I don't know what reasons:

此代码段仅适用于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>

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

So this leaves us with the wrapper solution:

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>

这篇关于使用translate3d和scale进行转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆