Как создать эффект наведения изображения курсора с помощью CSS и JS!
Пользовательские курсоры и эффекты наведения курсора — отличный способ произвести впечатление на пользователей вашего веб-сайта, независимо от того, создаете ли вы веб-сайт электронной коммерции или портфолио. Хорошим примером является эффект наведения изображения курсора, когда при наведении курсора на что-либо отображается изображение, вот мой способ его создания!
Настройка примера
Для этого примера я сделаю короткую и простую вертикальную навигацию с элементом nav
. В нем будет шесть элементов div
, а за пределами навигации находится элемент div
с классом "cursor"
, который будет нашим пользовательским курсором.
<nav>
<div>Lofi</div>
<div>Motivation</div>
<div>Profiles</div>
<div>Goals</div>
<div>Academics</div>
</nav>
<div class="cursor"></div>
Теперь мы добавляем CSS, который указывает размер шрифта, выравнивание и границу для каждого элемента навигации, кроме последнего.
html, body {
width: 99%;
height: 99%
}
body {
display: flex;
align-items: center;
}
nav {
font-size: 6rem;
display: grid;
}
nav > div:not(div:nth-child(5)) {
border-bottom: solid ;
}
@media (max-width: 480px) {
nav {
font-size: 4.8rem;
}
}
Создание и управление пользовательским курсором
Во-первых, мы должны удалить видимость курсора по умолчанию, установив для курсора (*
) веб-сайта значение none
. Затем мы создаем собственный курсор, который представляет собой элемент курсора, который мы создали ранее. Он будет иметь ширину (width
) и высоту (height
) 20px
, а радиус границы (border-radius
) будет установлен на 50%
, поэтому он станет кругом. Вы можете добавить для него любой цвет фона (background-color
), я выбрал black
, чтобы его было легко видно. Самая важная часть заключается в том, что вы устанавливаете фиксированное (fixed
) положение (position
), чтобы курсор всегда оставался в поле зрения, а события указателя (pointer-events)- none
, чтобы действия по умолчанию, связанные с тем, как будет работать курсор по умолчанию, не влияют на пользовательский. Наконец, вы устанавливаете размер фона (background-size
) для покрытия (cover
) и масштаб перехода transition
, оба они будут важны для эффектов при наведении в дальнейшем.
* {
cursor: none;
}
.cursor {
width: 20px;
height: 20px;
border-radius: 50%;
background-color: black;
/*Keeps our custom cursor on the user's screen*/
position: fixed;
pointer-events: none;
/*makes sure the background images will sort of fit the cursor*/
background-size: cover;
transition: scale 300ms;
}
Примечание
Я сказал о видимости курсора, а не о самом курсоре, поскольку компьютер по-прежнему выполняет действия курсора, например выделение текста, даже если курсор не отображается.
Теперь в Javascript мы создаем переменную, в которой будет храниться курсор.
let cursor = document.querySelector(".cursor");
Далее мы создадим функцию курсорконтрол с параметром e, который означает событие. В нем мы создаем переменные X
и Y
, которые используют e.clientX
и e.clientY
для определения координат того места, где должен находиться курсор, на основе движений мыши. Затем мы размещаем наш пользовательский курсор на основе наших координат, устанавливая его верхнюю позицию на y
и левую позицию на x
. Наконец, мы просто вызываем функцию в нашем прослушивателе событий mousemove
.
function cursorControl(e) {
//tracks the cursors coordinates
let x = e.clientX;
let y = e.clientY;
//places the custom cursor onto the cursor coordinates
cursor.style.top = `${y}px`;
cursor.style.left = `${x}px`;
}
document.addEventListener("mousemove", cursorControl);
Вот оно! Пользовательский курсор, теперь нам просто нужно добавить эффекты наведения.
Эффект роста курсора при наведении
Прежде чем мы перейдем к части
Javascript, нам нужно создать новый класс по имени cursorGrow
со свойством scale
,
равным 8
. Этот класс будет
добавляться к курсору всякий раз, когда он наводится на навигационный элемент div
.
.cursorGrow {
scale: 8;
}
Теперь в JS мы сохраняем все элементы навигации в переменную.
let divs = document.querySelectorAll("div:not(.cursor)");
Кроме того, мы создаем метод forEach
. Где для каждого div
в нашей навигации, когда курсор входит/наводит на них курсор, будет добавлен класс CSS CursorGrow
, в результате чего масштаб курсора увеличивается на 8, но когда курсор покидает класс, он удаляется, и размер возвращается к нормальный.
divs.forEach((div) => {
div.addEventListener("mouseenter", function () {
cursor.classList.add("cursorGrow");
});
div.addEventListener("mouseleave", function () {
cursor.classList.remove("cursorGrow");
});
});
Теперь, учитывая то, что мы уже сделали, код должен создать это (обязательно добавьте переход к курсору, если вы еще этого не сделали):
Эффект наведения курсора на изображение
И последнее, но не менее важное: мы наконец добавили эффект наведения изображения! Чтобы добавить каждое изображение, мы создадим классы CSS на основе каждого div и соответствующее им изображение.
/*Background image for each div based on their text*/
.lofi {
background-image: url('https://images.unsplash.com/photo-1585477281005-b83d4b47eba4?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D');
}
.motivation {
background-image: url('https://images.unsplash.com/photo-1556711905-4bd1b6603275?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D');
}
.webDev {
background-image: url('https://images.unsplash.com/photo-1498050108023-c5249f4df085?q=80&w=1772&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D');
}
.goals {
background-image: url('https://i.pinimg.com/564x/4d/ee/43/4dee438cb40321df2cb0cfb14a3c7811.jpg');
}
.academics {
background-image: url('https://i.pinimg.com/564x/f8/3d/8b/f83d8b8d17e4315caa647dab88e6addc.jpg');
}
Теперь мы могли бы сделать это аналогично нашему эффекту наведения при наведении роста, где мы продолжаем писать прослушиватели событий mouseenter
и mouseleave
, но это было бы слишком много кода. Вместо этого мы могли бы сделать цикл! Но сначала нам нужно сохранить имена каждого класса изображений в массиве и переменной divs
, которая у нас была раньше.
let divs = document.querySelectorAll("div:not(.cursor)");
const imageClassNames = ["lofi", "motivation", "webDev", "goals", "academics"];
Теперь о цикле. Это работает так: в цикле есть прослушиватели событий mouseenter
и mouseleave
, которые добавляют и удаляют классы из массива классов изображения. Всякий раз, когда класс добавляется в элемент div
, элементу div
присваиваются свойства класса, который является его фоновым изображением, но при удалении свойства класса также удаляются, как это происходит с classList.add()
и classList.remove()
работает.
Чтобы убедиться, что правильный класс соответствует правильному элементу div
, цикл переходит от 0 к длине массива, так что до тех пор, пока порядок в массиве divs
и массиве imageClassNames
, правильный элемент div
и правильное значение массива всегда совпадают. Так, например, он начинается с 0-го значения массива divs
, который является элементом div lofi
, и добавляет класс с именем 0-го значения imageClassNames
, который имеет значение lofi
всякий раз, когда мышь входит в элемент div
, но удаляет его, когда он покидает div
. Цикл делает это для каждого значения в классе изображения и массиве divs
и не позволяет нам писать постоянные прослушиватели событий в нашем коде.
const ImageClassNames = ["lofi", "motivation", "webDev", "goals", "academics"];
for (let i = 0; i < divs.length; i++) {
divs[i].addEventListener("mouseenter", () => {
cursor.classList.add(imageClassNames[i]);
});
divs[i].addEventListener("mouseleave", () => {
cursor.classList.remove(imageClassNames[i]);
});
}
Теперь у нас наконец-то должен появиться эффект наведения изображения курсора!
Заключение
Это действительно так! Мне потребовалось немало проб и ошибок, чтобы выбросить из головы этот эффект наведения курсора, но, в конце концов, оно того стоило, поэтому я захотел создать об этом блог! В своем Twitter я показываю больше своих работ по веб-разработке, разработке игр и даже 3D-блендеру. Следите за новостями и желаю вам отличного дня/ночи👋.