Создание анимации наклона мыши с перспективой и преобразованием

внешний интерфейс JavaScript CSS
Создание анимации наклона мыши с перспективой и преобразованием

Предисловие

Эта статья переведена сAnimate a Container on Mouse Over Using Perspective and Transform

Эта статья была впервые опубликована в моем личном блоге:Woohoo.Fe record.com/animate-ah-from…. При перепечатке прикрепите исходный адрес, чтобы можно было обновить источник.

Проект, над которым я работаю, должен показывать пользователю большое количество картинок.Обычные эффекты лайтбокса (приближение и отдаление и т.д.) немного скучноваты.Я решил сделать эффект отображения картинок более интерактивным и интересным : когда мышь перемещается по изображению, пусть изображение следует за наклоном при движении мыши.

Эффект следующий:

Проверьте это на codePen: https://codepen.io/MihaiIonescu/pen/MrLo

Выполнение этого эффекта требует одновременного использования CSS и JavaScript, следующее небольшое руководство поможет вам быстро разобраться.

Рекомендуется сначала понятьperspectiveа такжеtransformТогда прочитайте следующие уроки. Мы полностью поймем использование этих двух свойств в следующем руководстве.

Начинать

containerа такжеinner,containerЭлемент будет использовать свойство перспективы.

<div id="container">
    <div id="inner"></div>
</div>

В демонстрационных целях мы отображаем этот элемент в виде карточки в центре экрана:

body {
    /* Full screen width and height */
    width: 100%;
    min-height: 100vh;

    /* Centers the container in the middle of the screen */
    display: flex;
    justify-content: center;
    align-items: center;

    margin: 0;
    background-color: rgb(220, 220, 220);
}

#container {
    /* This will come into play later */
    perspective: 40px;
}

#inner {
    width: 20em;
    height: 18em;
    background-color: white;
}

Вы можете видеть, что в результате отображается белая карточка на сером фоне. Следует отметить, что в коде мы допускаем#containerCSS-перспектива40px, что эквивалентно указанию браузеру, что элемент находится в 40 пикселях от экрана. Позже, изменив свойство transforms, мы можем заставить его отображать эффект наклона вперед и назад в этом пространстве с помощью трехмерного вращения.

Используйте JavaScript

Сначала определите контроллер для событий мыши:

var container = document.getElementById('container');
var inner = document.getElementById('inner');

var onMouseEnterHandler = function(event) {
    update(event);
};
var onMouseLeaveHandler = function() {
    inner.style = "";
};
var onMouseMoveHandler = function(event) {
    if (isTimeToUpdate()) {
        update(event);
    }
};

container.onmouseenter = onMouseEnterHandler;
container.onmouseleave = onMouseLeaveHandler;
container.onmousemove = onMouseMoveHandler;

Этот контроллер включает в себя 3 аспекта:

  • Handler Functions: эти функции используются для обработки событий ввода, перемещения и ухода мыши.
  • Update Function:update()Эта функция не полностью написана в этом коде, ее функция заключается в изменении в зависимости от расстояния, на которое перемещается мышь.#innerНаклон , мы уточним эту функцию позже.
  • Time to Update Function:isTimeToUpdate()Эта функция не была написана, ее функция заключается в контролеupdate()Количество выполнений , только если его возвращаемое значение истинноupdate(). это чтобы уменьшитьupdate()количество выполнений для повышения производительности кода.

Приведенный выше код будет:

  • Войти с помощью мыши#containerкогда, сделай#innerСоздание 3D-вращения.
  • когда мышь закончилась#containerПри перемещении во время внутреннего движения изменение в соответствующем интервале времени#inner
  • #container, сброс настроек#innerСтиль.

Давайте взглянем на содержимое функции iStimeToupDate, она может управлятьupdate()Частота звонков:

var counter = 0;
var updateRate = 10;
var isTimeToUpdate = function() {
    return counter++ % updateRate === 0;
};

когдаcounterзначениеupdateRateПри целочисленном кратном обновлении произойдет. Этот код указываетisTimeToUpdate()Обновление будет происходить только один раз каждые 10 выполнений.

мышь

Затем мы создаем объект для записи положения мыши.Напоминаем, этот код может показаться сложным для новичков в js, но на самом деле его очень легко понять.

// Init
var container = document.getElementById('container');
var inner = document.getElementById('inner');

// Mouse 
var mouse = {
    _x: 0,
    _y: 0,
    x: 0,
    y: 0,
    updatePosition: function(event) {
        var e = event || window.event;
        this.x = e.clientX - this._x;
        this.y = (e.clientY - this._y) * -1;
    },
    setOrigin: function(e) {
        this._x = e.offsetLeft + Math.floor(e.offsetWidth/2);
        this._y = e.offsetTop + Math.floor(e.offsetHeight/2);
    },
    show: function() { return '(' + this.x + ', ' + this.y + ')'; }
}

// 设置鼠标的中心位置
mouse.setOrigin(container);

Давайте поговорим об этом коде, который в основном включает в себя эти функции:

  • show(): используется для отображения текущей позиции мыши (вы можете использовать console.log() или что-то еще).
  • setOrigin(): Установить начальные координаты мыши, т.е.#containerЦентральное положение установлено на(0,0).
  • updatePosition(): Получить текущий родственник мыши(0,0)Координатное положение.

Это то, что мы упоминали вышеupdate()функция:

var update = function(event) {
    mouse.updatePosition(event);
        updateTransformStyle(
        (mouse.y / inner.offsetHeight/2).toFixed(2),
        (mouse.x / inner.offsetWidth/2).toFixed(2)
    );
};

var updateTransformStyle = function(x, y) {
    var style = "rotateX(" + x + "deg) rotateY(" + y + "deg)";
    inner.style.transform = style;
    inner.style.webkitTransform = style;
    inner.style.mozTransform = style;
    inner.style.msTransform = style;
    inner.style.oTransform = style;
};

  • update(): обновление при изменении положения мыши#innerстиль.
  • updateTransformStyle(): обновить свойство преобразования стиля элемента.

После вышеприведенного кода у нас как будто появился королевский город.При движении мышки карта тоже будет вращаться в 3D под таким же углом, но выглядит это не слишком шелковисто:

Есть идеи, почему? Потому что мы настроили его на производительностьisTimeToUpdate()Обновление происходит каждые 10 раз! Это привело к заиканию между обновлениями.

Проверьте это на codePen: https://codepen.io/MihaiIonescu/pen/VQWWgj

Как решить? Используйте переходы CSS, чтобы сделать эту анимацию гладкой и шелковистой.

Используйте переходы

#inner {
    transition: transform 0.5s;
}

Вы можете установить значение перспективы и продолжительность перехода по своему вкусу. Взгляните на окончательный результат:

Проверьте это на codePen: https://codepen.io/MihaiIonescu/pen/MQoodL

Суммировать

С помощью этого простого метода мы делаем изображение более интерактивным, и вы можете применить этот метод к любому элементу, например к формам, всплывающим окнам и т. д.

Кроме того, вот чистый метод css для достижения того же эффекта, интересующиеся студенты могут узнать о нем: https://codepen.io/onediv/pen/BprVzp