使用 translate3d 和 scale 进行转换
Using translate3d and scale for transformations
我想制作一个 div
跟随光标并同时 grows/shrinks 作为动画。
我使用 top
和 left
更改了 div
的位置,但动画有时有点断断续续。
我想用 translate3d
制作 animations smooth,但我很难将 translate3d
与 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
转换值
我想到了这个,但它不起作用
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-variables 来更新动画中的翻译值,除了 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>
我想制作一个 div
跟随光标并同时 grows/shrinks 作为动画。
我使用 top
和 left
更改了 div
的位置,但动画有时有点断断续续。
我想用 translate3d
制作 animations smooth,但我很难将 translate3d
与 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
转换值
我想到了这个,但它不起作用
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-variables 来更新动画中的翻译值,除了 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>