Как сделать данную анимацию более плавной? Так как сейчас она деревянная. Magnetic cursor JS + CSS

const inner = document.querySelector('.cursor-inner'),
      outer = document.querySelector('.cursor-outer');

document.addEventListener('mousemove', e => {
  inner.style.top = e.pageY + 'px';
  inner.style.left = e.pageX + 'px';
  outer.style.top = e.pageY + 'px';
  outer.style.left = e.pageX + 'px';
});
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');

@media (min-width: 1400px) {
  html { font-size: calc(5px + (12.5 - 5)*((100vw - 768px)/(1920 - 768))); }
}

@media (max-width: 1399px) and (min-width: 1024px) {
  html { font-size: calc(7px + (12.5 - 5)*((100vw - 768px)/(1920 - 768))); }
}

@media screen and (max-width: 1023px) and (min-width: 768px) {
  html { font-size: calc(8.3px + 1.5*(100vw - 768px)/(1024 - 768)); }
}

@media screen and (max-width: 767px) {
  html { font-size: calc(8.6px + (19.6 - 8.6)*(100vw - 320px)/447); }
}

body {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Monsterrat", sans-serif;
  overflow: hidden;
  background: black;
  color: white;
  cursor: none;
}

h1 { font-size: 10vw; }

.content:hover ~ .cursor-outer { opacity: 0; }

.content:hover~.cursor-inner {
  width: 6rem;
  height: 6rem;
  mix-blend-mode: difference;
}

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  transform: translate(-50%, -50%);
  border-radius: 100%;
  z-index: 99;
  pointer-events: none;
}

.cursor-inner {
  width: .5rem;
  height: .5rem;
  background: white;
  transition: 0.3s;
}

.cursor-outer {
  width: 5rem;
  height: 5rem;
  border: 1px solid white;
}
<div class="content">
  <h1>Mouse Cursor</h1>
</div>

<div class="cursor-inner cursor"></div>
<div class="cursor-outer cursor"></div>

Вот пример когда данная анимация плавная: baha-dev.space


Ответы (2 шт):

Автор решения: highpassion

Изменил transition-timing-function на ease-out - замедление в конце

const inner = document.querySelector('.cursor-inner'),
      outer = document.querySelector('.cursor-outer')

document.addEventListener("mousemove", e => {
    inner.style.top = e.pageY + "px"
    inner.style.left = e.pageX + "px"
    
    outer.style.top = e.pageY + "px"
    outer.style.left = e.pageX + "px"
})
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');

@media (min-width: 1400px) {
    html { 
        font-size: calc(5px + (12.5 - 5)*((100vw - 768px)/(1920 - 768)));
    }
}

@media (max-width: 1399px) and (min-width: 1024px) {
    html {
        font-size: calc(7px + (12.5 - 5)*((100vw - 768px)/(1920 - 768)));
    }
}

@media screen and (max-width: 1023px) and (min-width: 768px) {
    html {
        font-size: calc(8.3px + 1.5*(100vw - 768px)/(1024 - 768));
    }    
}

@media screen and (max-width: 767px) {
    html {  
        font-size: calc(8.6px + (19.6 - 8.6)*(100vw - 320px)/447);
    }
}

body {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Monsterrat", sans-serif;
  overflow: hidden;
  background: black;
  color: white;
  cursor: none;
}

h1 {
  font-size: 10vw;
}

.content:hover ~ .cursor-outer {
   opacity: 0;
}

.content:hover ~ .cursor-inner {
  width: 6rem;
  height: 6rem;
  mix-blend-mode: difference;
}

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  transform: translate(-50%, -50%);
  border-radius: 100%;
  z-index: 99;
  pointer-events: none;
}

.cursor-inner {
  width: .5rem;
  height: .5rem;
  background: white;
  transition: 0.3s ease-out;
}

.cursor-outer {
   width: 5rem;
   height: 5rem;
   border: 1px solid white;
     
}
<div class="content">
    <h1>Mouse Cursor</h1>
</div>

<div class="cursor-inner cursor"></div>
<div class="cursor-outer cursor"></div>

→ Ссылка
Автор решения: yar85

Переход (transition) размера через width и height == медленно и печально.
Переход размера через transform шустрее, благодаря аппаратному ускорению:

const inner = document.querySelector('.cursor-inner'),
      outer = document.querySelector('.cursor-outer');

document.addEventListener('mousemove', e => {
  inner.style.top = outer.style.top = e.pageY + 'px';
  inner.style.left = outer.style.left = e.pageX + 'px';
});
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');

@media (min-width: 1400px) {
  html { font-size: calc(5px + (12.5 - 5)*((100vw - 768px)/(1920 - 768))); }
}

@media (max-width: 1399px) and (min-width: 1024px) {
  html { font-size: calc(7px + (12.5 - 5)*((100vw - 768px)/(1920 - 768))); }
}

@media screen and (max-width: 1023px) and (min-width: 768px) {
  html { font-size: calc(8.3px + 1.5*(100vw - 768px)/(1024 - 768)); }
}

@media screen and (max-width: 767px) {
  html { font-size: calc(8.6px + (19.6 - 8.6)*(100vw - 320px)/447); }
}

body {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Monsterrat", sans-serif;
  overflow: hidden;
  background: black;
  color: white;
  cursor: none;
}

h1 { font-size: 10vw; }

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  transform: translate(-50%, -50%);
  border-radius: 100%;
  z-index: 99;
  pointer-events: none;
}

.cursor-inner {
  width: 6rem;
  height: 6rem;
  transform-origin: center;
  transform: translate(-50%, -50%) scale(calc(1 / 12));
  background: white;
  transition: transform 0.3s ease;
}

.cursor-outer {
  width: 5rem;
  height: 5rem;
  border: 1px solid white;
}

.content:hover ~ .cursor-inner {
  transform: translate(-50%, -50%) scale(1);
  mix-blend-mode: difference;
}

.content:hover ~ .cursor-outer { opacity: 0; }
<div class="content">
  <h1>Mouse Cursor</h1>
</div>

<div class="cursor-inner cursor"></div>
<div class="cursor-outer cursor"></div>

Возможны доп. оптимизации в CSS (эффективность которых зависит от браузера):

  • will-change: top, left, transform;
  • backface-visibility: hidden;
  • замена сглаженного просчета перехода на steps(n), конечно же с соотв. сокращением длительности перехода
  • (в будущем*) замена установки координат инлайн-стилем с top и left на передачу смещения в translate через attr и data-атрибуты.

* Сейчас attr так не работает, ни в одном из браузеров - но возможность такого использования предусмотрена текущими версиями спецификации CSS Values and Units (Level 3+), и за три с лишним года предложение не исключили => есть шансы на то что мы все же получим полноценный attr когда-нибудь.

→ Ссылка