Nano Hash - криптовалюты, майнинг, программирование

FabricJS Сенсорное панорамирование/масштабирование всего холста

Мне нужно включить сенсорное масштабирование/панорамирование на холсте FabricJS. Существуют библиотеки, которые разрешают такое поведение на изображении (см. pinch-zoom-canvas). или с помощью событий щелчка мыши (см. эту Fiddle), но я не могу понять События touch:gesture подключены правильно.

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

Я пробовал такие варианты кода:

    canvas.on({
        'touch:gesture': function() {
            var text = document.createTextNode(' Gesture ');
            info.insertBefore(text, info.firstChild);
            // Handle zoom only if 2 fingers are touching the screen
            if (event.e.touches && event.e.touches.length == 2) {
                // Get event point
                var point = new fabric.Point(event.self.x, event.self.y);
                // Remember canvas scale at gesture start
                if (event.self.state == "start") {
                    zoomStartScale = self.canvas.getZoom();
                }
                // Calculate delta from start scale
                var delta = zoomStartScale * event.self.scale;
                // Zoom to pinch point
                self.canvas.zoomToPoint(point, delta);
            }

        },
        'touch:drag': function(e) {
            panning = true;
            var text = document.createTextNode(' Dragging ');
            info.insertBefore(text, info.firstChild);
            if (panning && e && e.e) {
                debugger;
                var units = 10;
                var delta = new fabric.Point(e.e.movementX, e.e.movementY);
                canvas.relativePan(delta);
            }
            panning = false;
        },
        'touch:longpress': function() {
            var text = document.createTextNode(' Longpress ');
            info.insertBefore(text, info.firstChild);
        }
    });

Но ничего не происходит, когда я тестирую на iPhone/iPad.

14.07.2017

Ответы:


1

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

    canvas.on({
        'touch:gesture': function(e) {
            if (e.e.touches && e.e.touches.length == 2) {
                pausePanning = true;
                var point = new fabric.Point(e.self.x, e.self.y);
                if (e.self.state == "start") {
                    zoomStartScale = self.canvas.getZoom();
                }
                var delta = zoomStartScale * e.self.scale;
                self.canvas.zoomToPoint(point, delta);
                pausePanning = false;
            }
        },
        'object:selected': function() {
            pausePanning = true;
        },
        'selection:cleared': function() {
            pausePanning = false;
        },
        'touch:drag': function(e) {
            if (pausePanning == false && undefined != e.e.layerX && undefined != e.e.layerY) {
                currentX = e.e.layerX;
                currentY = e.e.layerY;
                xChange = currentX - lastX;
                yChange = currentY - lastY;

                if( (Math.abs(currentX - lastX) <= 50) && (Math.abs(currentY - lastY) <= 50)) {
                    var delta = new fabric.Point(xChange, yChange);
                    canvas.relativePan(delta);
                }

                lastX = e.e.layerX;
                lastY = e.e.layerY;
            }
        }
    });

Абсолютное выражение ~50px if/then позволяет избежать перетаскивания далеко от последней точки, что приводит к прыжку холста. Также приостановлено панорамирование, чтобы иметь возможность перемещать объект независимо. Код Pinch/Zoom был найден в ветке проблем github.

16.07.2017
  • классный! действительно большая помощь для всех пользователей ткани! 07.12.2017
  • Возник вопрос: я попробовал этот ответ, но мой canvas не получает touch:gesture, кажется, что только объекты получают touch:gesture? Очень хотелось бы знать, как ваш холст получает событие touch:gesture, спасибо! Кстати, я использую 1.7.20 (с build_with_gestures). 13.12.2017
  • Можно ли масштабировать только элементы? Я хотел бы увеличить всю страницу, если попытаюсь увеличить фон холста. 15.01.2021
  • @Simone вы, вероятно, могли бы использовать «object: hover», чтобы изменить масштаб объекта. Я бы создал отдельный вопрос, чтобы указать желаемую функциональность. 16.01.2021

  • 2

    У меня возникли проблемы с тем, чтобы панорамирующая часть кода Лоренса работала на Fabric 2.3.3. Поэтому, если кто-то столкнется с той же проблемой, я хотел бы поделиться своим решением.

    Моя проблема заключалась в том, что я не мог заставить работать панорамирование на своем смартфоне, хотя оно работало на ПК. После некоторой отладки я обнаружил, что могу решить эту проблему, заменив e.e.layerX на e.self.xe.e.layerY на e.self.y).

    Вот полный измененный код:

    canvas.on({
        'touch:gesture': function(e) {
            if (e.e.touches && e.e.touches.length == 2) {
                pausePanning = true;
                var point = new fabric.Point(e.self.x, e.self.y);
                if (e.self.state == "start") {
                    zoomStartScale = canvas.getZoom();
                }
                var delta = zoomStartScale * e.self.scale;
                canvas.zoomToPoint(point, delta);
                pausePanning = false;
            }
        },
        'object:selected': function() {
            pausePanning = true;
        },
        'selection:cleared': function() {
            pausePanning = false;
        },
        'touch:drag': function(e) {
            if (pausePanning == false && undefined != e.self.x && undefined != e.self.x) {
                currentX = e.self.x;
                currentY = e.self.y;
                xChange = currentX - lastX;
                yChange = currentY - lastY;
    
                if( (Math.abs(currentX - lastX) <= 50) && (Math.abs(currentY - lastY) <= 50)) {
                    var delta = new fabric.Point(xChange, yChange);
                    canvas.relativePan(delta);
                }
    
                lastX = e.self.x;
                lastY = e.self.y;
            }
        }
    });}
    
    05.08.2018
  • Спасибо тебе за это!!! У меня тоже были проблемы с панорамированием холста, и это исправило это. 31.12.2020

  • 3

    Мне удалось добиться мультисенсорного панорамирования и масштабирования с помощью события mouse:wheel.

    При масштабировании щипком — в большинстве браузеров обычно также выдается кнопка ctrl, чтобы отличить операцию прокрутки от операции прокрутки.

    Затем я использую свойства DeltaX и DeltaY события Fabric для масштабирования или панорамирования, как в sample код, который они предоставили.

    Каждое место, которое я называю setState ниже, должно быть переменной вне функции, если вы не используете React.

        this.canvas.on("mouse:wheel", opt => {
          if (!this.canvas.viewportTransform) {
            return;
          }
    
          var evt: any = opt.e;
          if (evt.ctrlKey === true) {
            var evt: any = opt.e;
            var deltaY = evt.deltaY;
            var zoom = this.canvas.getZoom();
            zoom = zoom - deltaY / 100;
            if (zoom > 20) zoom = 20;
            if (zoom < 0.01) zoom = 0.01;
            this.canvas.zoomToPoint(
              new fabric.Point(evt.offsetX, evt.offsetY),
              zoom
            );
          } else {
            console.log("Scrolling!!");
    
            //inverted scrolling enabled. Remove the -1 multiplier to disable
    
            this.canvas.viewportTransform[4] += (evt.deltaX)*-1; 
            this.canvas.viewportTransform[5] += (evt.deltaY)*-1;
            this.canvas.requestRenderAll();
            this.setState({ lastPosX: evt.clientX });
            this.setState({ lastPosY: evt.clientY });
          }
          opt.e.preventDefault();
          opt.e.stopPropagation();
        });
    
    28.11.2019
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..