Увеличение и уменьшение изображения на HTML5 Canvas: Zoom к курсору

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для того чтобы реализовать масштабирование холста с фокусом в точке, которую обозначает положение курсора, требуется изменить масштаб и «сдвинуть» контекст холста. Весь процесс можно разбить на следующие этапы:

  1. Смещаем контекст к месту, где расположен курсор.
  2. Применяем масштабирование с установленным коэффициентом.
  3. Совершаем обратное смещение контекста, учитывая масштабирование.

Ниже представлен пример кода на JavaScript, позволяющего выполнить описанный процесс:

JS
Скопировать код
function zoomAtCursor(canvas, ctx, zoomFactor, cursorX, cursorY) {
    // Рассчитываем размеры холста
    var rect = canvas.getBoundingClientRect();
    // Вычисляем смещение точки масштабирования
    var offsetX = (cursorX – rect.left) * (1 – zoomFactor);
    var offsetY = (cursorY – rect.top) * (1 – zoomFactor);
    // Применяем комбинацию функций смещения и масштабирования
    ctx.translate(offsetX, offsetY);
    ctx.scale(zoomFactor, zoomFactor);
    ctx.translate(-offsetX, -offsetY);
    // Контекст подготовлен для рисования.
}

Для того чтобы осуществляла масштабирование с фокусом на курсоре, следует вызвать функцию zoomAtCursor и передать ей коэффициент масштабирования и координаты курсора.

Кинга Идем в IT: пошаговый план для смены профессии

Важные нюансы

Обработка событий мыши и касаний

При реализации масштабирования наперёд учтём различные варианты взаимодействия пользователей с системой:

  • Клик мыши для увеличения относительного размера.
  • Shift + Клик для уменьшения относительного размера.
  • Перемещение мыши с зажатой кнопкой для плавного перемещения изображения.
  • Одновременное касание двумя пальцами для масштабирования на touch-устройствах.

Матричные преобразования и вопрос производительности

В процессе масштабирования рекомендуется использовать функцию ctx.setTransform, которая поможет избежать накопления трансформаций, повысив тем самым производительность. После каждого масштабирования следует сбросить трансформации:

JS
Скопировать код
ctx.setTransform(1, 0, 0, 1, 0, 0); // Сброс к исходному состоянию

Очистка холста

Необходимо очищать холст перед каждым процессом отрисовки, чтобы старые кадры не воздействовали на новые:

JS
Скопировать код
ctx.clearRect(0, 0, canvas.width, canvas.height); // Стереть все содержимое

Использование сторонних библиотек и внешних функций

Библиотеки, такие как Loupe, CanvasZoom или Scroller, могут существенно облегчить вашу работу, выполняя сложные вычисления за вас, в частности, инверсию матриц.

Плавное масштабирование

Для реализации плавного масштабирования используем функцию requestAnimationFrame. Это особенно актуально для устройств с ограниченной производительностью:

JS
Скопировать код
function animateZoom(canvas, ctx, targetZoom, cursorX, cursorY, steps) {
    var currentStep = 0;
    (function step() {
        if (currentStep < steps) {
            var zoomFactor = 1 + (targetZoom – 1) * currentStep / steps;
            zoomAtCursor(canvas, ctx, zoomFactor, cursorX, cursorY);
            currentStep++;
            requestAnimationFrame(step); // Повторяем действие
        }
    })();
}

Визуализация

Представьте себя астронавтом в поисках новых планет. Ваш телескоп фокусирует изображение одной из планет, которая постепенно монополизирует ваше поле зрения, оказываясь в его центре.

Markdown
Скопировать код
До масштабирования: [👨‍🚀🔭🌌🪐] (Вы обнаружили некую планету)
После масштабирования: [👨‍🚀🔭🪐🌌] (Теперь планета в центре вашего внимания)

Процесс масштабирования холста можно сравнить с работой телескопа, где курсор мыши выступает в роли точки сведения.

Markdown
Скопировать код
Перед масштабированием: [🖼️🐁🌌🌠] (Курсор указывает на звезду)
После масштабирования: [🌌🌠🐁🌌] (Звезда остаётся под курсором независимо от масштаба)

Такой подход позволяет сохранить концентрацию внимания на определённом объекте в процессе масштабирования.

Полезные материалы

  1. API HTML-холста – Веб-API | MDN — подробное руководство MDN по API холста.
  2. Получение точного положения мыши на холсте – Stack Overflow — обсуждение подходов к определению положения курсора на холсте.
  3. Coding Dude: Ресурс о веб-разработке, JavaScript, HTML, CSS, SEO — собрание информации о матрицах аффинных преобразований, актуальных для масштабирования.
  4. GitHub – anvaka/panzoom: Библиотека панорамирования и масштабирования – библиотека, эффективная для задач масштабирования веб-элементов.
  5. Пример на CodePen – демонстрация масштабирования холста с учетом положения курсора.