Анализ принципа жестов и практики математических знаний в HTML5

внешний интерфейс JavaScript HTML
Анализ принципа жестов и практики математических знаний в HTML5

Анализ принципа жестов и практики математических знаний в HTML5

введение

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

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

В основном объясните пять жестов, которые часто используются в проектах:

  • тянуть:drag
  • Сожмите, чтобы увеличить:pinch
  • Вращение двумя пальцами:rotate
  • Увеличение одним пальцем:singlePinch
  • Вращение одним пальцем:singleRotate

Tips :
потому чтоtapа такжеswipeВключено много базовых библиотек, поэтому они не включены для переносимости, но при необходимости могут быть расширены;

Принцип реализации

Как мы все знаем, все жесты основаны на нативных событиях браузера.touchstart, touchmove, touchend, touchcancelОсуществляется инкапсуляция верхнего уровня, поэтому идея инкапсуляции состоит в том, чтобы вызывать склад через независимые события.handleBus, то в родномtouchУточненное время в событии инициирует и передает вычисленное значение параметра для завершения операции жеста. Принцип реализации относительно прост и понятен. Давайте не будем спешить. Давайте сначала проясним некоторые используемые математические понятия и объединим код, чтобы применить математику к практическим задачам. Математическая часть может быть скучной, но я надеюсь, что вы продолжите читать, и я верю в это. принесет много пользы.

Функция базовых математических знаний

Наша общая система координат принадлежит линейному пространству, или векторному пространству. Это пространство представляет собой набор точек и векторов;

Точка

Может пониматься как наша точка координат, например, начало координатO(0,0),A(-1,2), через собственный объект событияtouchesВы можете получить координаты точки касания, параметрыindexПредставляет первую точку контакта;104625946-59847e999911a_articlex

 

Вектор

это система координатСегменты линии с размером и направлением, например, по происхождениюO(0,0)точка-точкаA(1,1)сегмент стрелки , называемый векторомa,ноa=(1-0,1-0)=(1,1);

Как показано на рисунке ниже, гдеiа такжеjВектор называется единичным вектором системы координат, также называемым базовым вектором.Наша общая единица системы координат равна1,которыйi=(1,0);j=(0,1);

1358258230-59847ed4a6e63_articlex

Функция для получения вектора:3755500458-59847ef1bc2ba_articlex

 

вектор по модулю

представлятьдлина вектора, обозначаемый как|a|, является скаляром только с величиной и без направления;

Геометрический смыслx,y— гипотенуза прямоугольного треугольника с прямыми сторонами, вычисленная по теореме Пифагора;

1893784804-59847f0835cd5_articlex

getLengthфункция:

3924861912-59847f1f13487_articlex

Произведение векторов

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

Когда a=(x1,y1),b=(x2,y2), то a·b=|a|·|b|·cosθ=x1·x2+y1·y2;

теорема о коллинеарности

коллинеарны, т. е. два вектора находятся впараллельносостояние, когдаa=(x1,y1),b=(x2,y2), то существует единственное действительное число λ такое, чтоa=λb, после подстановки точки координат можно получитьx1·y2= y1·x2;

Поэтому, когдаx1·y2-x2·y1>0, как наклонka > kb, так что в это времяbвектор относительноaВектор принадлежит вращению по часовой стрелке, иначе против часовой стрелки;

Угол поворота

Используя формулу количественного произведения, мы можем экстраполировать, чтобы найти угол между двумя векторами:

cosθ=(x1·x2+y1·y2)/(|a|·|b|);

Тогда мы можем определить направление вращения по теореме о коллинеарности, и функция определяется как:

2839618888-59847f36e65f4_articlex

Матрицы и преобразования

Поскольку наиболее важной особенностью пространства является то, что оно может приспосабливаться к движению, в линейном пространстве

Мы используем векторы для описания объектов, а матрицы — для описания движения объектов;

И как матрица описывает движение?

Мы знаем, что вектор может быть определен базовым вектором системы координат, напримерa=(-1,2), мы обычно соглашаемся с базисными векторами i = (1,0) и j = (0,1), поэтому:

a = -1i + 2j = -1(1,0) + 2(0,1) = (-1+0,0+2) = (-1,2);

Трансформация матрицы, на самом деле, состоит в том, чтобы преобразовать базовый вектор через матрицу, что завершает преобразование вектора;

Например, каштан выше, поставьтеaВектор преобразуется матрицей (1,2,3,0), в этот момент базисный векторiЗависит от(1,0)превратиться в(1,-2)а такжеjЗависит от(0,1)превратиться в(3,0), следуя приведенному выше выводу, то

a = -1i + 2j = -1(-1,2) + 2(3,0) = (5,-2);

Как показано ниже:
Рисунок A представляет систему координат до преобразования, в настоящее времяa=(-1,2), после преобразования матрицы базисный векторi,jПреобразование вызвало преобразование системы координат, которая стала следующей фигурой B, поэтомуaвектор по(-1,2)превратился в(5,-2);

На самом деле связь между вектором и системой координат не меняется (a = -1i+2j), это базовый вектор, который вызывает изменение системы координат, а затем система координат продолжает использовать ассоциацию, чтобы вызвать изменение вектора;

3287703221-59848033abb15_articlex

Объединить код

На самом деле CSStransformРавные преобразования выполняются через матрицы, которые мы обычно пишемtranslate/rotateРавный синтаксис похож на упакованный синтаксический сахар, который прост в использовании и быстро преобразуется в форму матрицы на нижнем уровне. Напримерtransform:translate(-30px,-30px)После компиляции он будет преобразован вtransform : matrix(1,0,0,1,30,30);

Обычно в двумерной системе координат для описания всех преобразований достаточно только матрицы 2X2, но поскольку CSS находится в 3D-среде, в CSS используется матрица 3X3, которая выражается как:

521131991-5984804c9c4ae_articlex

Третий ряд0,0,1представляет собойzПараметры по умолчанию для осей. В этой матрице(a,b)является координатной осьюiбаза, и(c,d)как дляjоснование,eдляxсмещение оси,fдляyСмещение оси, поэтому хорошо понятен верхний каштан,translateне привело кi,jБаза изменена, просто смещение,следовательноtranslate(-30px,-30px) ==> matrix(1,0,0,1,30,30)~

всеtransformзаявление, произойдет соответствующее преобразование, как показано ниже:

// 发生偏移,但基向量不变;
transform:translate(x,y) ==> transform:matrix(1,0,0,1,x,y)
 
// 基向量旋转;
transform:rotate(θdeg)==> transform:matrix(cos(θ·π/180),sin(θ·π/180),-sin(θ·π/180),cos(θ·π/180),0,0)
 
// 基向量放大且方向不变;
transform:scale(s) ==> transform:matrix(s,0,0,s,0,0)

translate/rotate/scaleСинтаксис очень мощный и делает наш код более читабельным и простым в написании, ноmatrixобладает более мощными конверсионными характеристиками, благодаряmatrix, можно трансформировать как угодно, например, наш общийзеркальная симметрия,transform:matrix(-1,0,0,1,0,0);

4292507316-5984806781903_articlex

MatrixTo

ОднакоmatrixНесмотря на то, что он мощный, он не очень удобочитаем, и наши записи выполняются черезtranslate/rotate/scaleсвойства, однако поgetComputedStyleчитатьtransformно этоmatrix:

transform:matrix(1.41421, 1.41421, -1.41421, 1.41421, -50, -50);

Как изменился этот элемент? . Это было сбито с толку. -_-|||

Поэтому у нас должен быть способmatrixпереводится на то, что нам более знакомоtranslate/rotate/scaleПоняв принцип, мы можем приступить к выполнению ~

Мы знаем, что первые 4 параметраrotateа такжеscaleВлияние , имеет две переменные, поэтому необходимо перечислить два неравенства согласно приведенному выше преобразованию через первые два параметра:

cos(θ·π/180)*s=1,41421;

sin(θ·π/180)*s=1,41421;

Разделив два неравенства, легко найтиθа такжеs, идеально! ! Функция выглядит следующим образом:

1996102881-5984807d26d7f_articlex

Принцип жестов

Затем мы применяем вышеуказанные функции к реальной среде, моделируем работу жестов с помощью диаграмм и кратко объясняем принципы расчета жестов. Я надеюсь, что после понимания этих основных принципов вы сможете создавать более крутые жесты, как это сделали мы вmacТо же самое используется на тачпаде.

Пример ниже:

Точка: представляет собой точку касания пальца;

Сегмент пунктирной линии между двумя точками: представляет собой вектор, образованный операцией двумя пальцами;

вектор/точка: представляет начальный вектор/начальную точку, полученную при запуске касания;

b вектор/точка B: представляет собой вектор/точку в реальном времени, полученную во время touchmove;

Формула внизу оси представляет вычисляемое значение;

Перетаскивание (событие перетаскивания)

602224203-5984808fdd5cf_articlex

Изображение выше представляет собой симуляцию жеста перетаскивания.Aпереместить точку наBДело в том, что мы хотим вычислить смещение этого процесса;

Поэтому мыtouchstartЗапишите координаты начальной точки A в:

// 获取初始点A;
let startPoint = getPoint(ev,0);

затем вtouchmoveПолучить текущую точку в событии и рассчитать ее в режиме реального времени△xа также△y:

// 实时获取初始点B;
let curPoint = getPoint(ev,0);
 
// 通过A、B两点,实时的计算出位移增量,触发 drag 事件并传出参数;
_eventFire('drag', {
    delta: {
        deltaX: curPoint.x - startPoint.x,
        deltaY: curPoint.y - startPoint.y,
    },
    origin: ev,
});

Tips: fireФункция пройдена и выполненаdragСклад обратного вызова, соответствующий событию, может быть;

Щепотка (щипок, чтобы увеличить)

Вышеприведенное изображение является симуляцией щипкового зума, щипковогоaвекторное увеличение доbвектор, через начальное состояниеaСумма по модулю вектораtouchmoveПриобретенныйbВычислите модуль вектора, чтобы получить значение масштабирования:

// touchstart中计算初始双指的向量模;
let vector1 = getVector(secondPoint, startPoint);
let pinchStartLength = getLength(vector1);
 
// touchmove中计算实时的双指向量模;
let vector2 = getVector(curSecPoint, curPoint);
let pinchLength = getLength(vector2);
this._eventFire('pinch', {
    delta: {
        scale: pinchLength / pinchStartLength,
    },
    origin: ev,
});

Поворот (вращение двумя пальцами)

858061720-598480b5a3ad5_articlex

Первоначально двунаправленный векторa, повернут наbвектор,θэто значение, которое нам нужно, поэтому просто передайтеgetAngleФункция для нахождения угла поворота:

// a向量;
let vector1 = getVector(secondPoint, startPoint);
 
// b向量;
let vector2 = getVector(curSecPoint, curPoint);
 
// 触发事件;
this._eventFire('rotate', {
    delta: {
        rotate: getAngle(vector1, vector2),
    },
    origin: ev,
});

singlePinch (зум одним пальцем)

3796387613-598480cc21d2f_articlex

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

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

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

изображеноaВекторное масштабирование одним пальцемbВектор, центр операнда (квадрата) увеличен, а значение масштаба равноbпо модулю вектора /aмодуль вектора;

// 计算单指操作时的基准点,获取operator的中心点;
let singleBasePoint = getBasePoint(operator);
 
// touchstart 中计算初始向量模;
let pinchV1 = getVector(startPoint,singleBasePoint);
singlePinchStartLength = getLength(pinchV1);
 
// touchmove 中计算实时向量模;
pinchV2 = getVector(curPoint, singleBasePoint);
singlePinchLength = getLength(pinchV2);
 
// 触发事件;
this._eventFire('singlePinch', {
    delta: {
        scale: singlePinchLength / singlePinchStartLength,
    },
    origin: ev,
});

singleRotate (вращение одним пальцем)

2855252767-598480e13aa7d_articlex

В сочетании с масштабированием одним пальцем и вращением двумя пальцами вы можете легко узнатьθ- нужный нам угол поворота;

// 获取初始向量与实时向量
let rotateV1 = getVector(startPoint, singleBasePoint);
let rotateV2 = getVector(curPoint, singleBasePoint);
 
// 通过 getAngle 获取旋转角度并触发事件;
this._eventFire('singleRotate', {
    delta: {
        rotate: getAngle(rotateV1, rotateV2),
    },
    origin: ev,
});

Приращение движения

из-заtouchmoveСобытие представляет собой высокочастотное триггерное событие в реальном времени. Фактически операция перетаскивания срабатывает N раз.touchmoveсобытие, поэтому вычисленное значение является только приращением, т. е. представляет собойtouchmoveЗначение, добавленное событием, представляет собой лишь небольшое значение, а не конечное значение результата, поэтому его необходимо определятьmtouch.jsДанные о местоположении хранятся извне, аналогично:

//    真实位置数据;
let dragTrans = {x = 0,y = 0};
 
// 累加上 mtouch 所传递出的增量 deltaX 与 deltaY;
dragTrans.x += ev.delta.deltaX;
dragTrans.y += ev.delta.deltaY;
 
// 通过 transform 直接操作元素;
set($drag,dragTrans);

исходное положение

Внешнее обслуживание данных о местоположении, если начальное значение установлено на 0 непосредственно, как описано выше, обеспечивается с помощью css.transformЭлемент атрибута не может быть правильно распознан, что приведет к мгновенному возврату элемента операции при его запуске.(0,0)Следовательно, нам нужно сначала получить реальное значение позиции элемента, а затем поддерживать и оперировать им. На этом этапе нам нужно использовать вышеупомянутыйgetComputedStyleметод сmatrixToфункция:

// 获取css transform属性,此时得到的是一个矩阵数据;
// transform:matrix(1.41421,1.41421,-1.41421,1.41421,-50,-50);
let style = window.getComputedStyle(el,null);
let cssTrans = style.transform || style.webkitTransform;
 
// 按规则进行转换,得到:
let initTrans = _.matrixTo(cssTrans);
 
// {x:-50,y:-50,scale:2,rotate:45};
// 即该元素设置了:transform:translate(-50px,-50px) scale(2) rotate(45deg);

Эпилог

На данный момент я считаю, что у всех есть базовое понимание принципов жестов.Основываясь на этих принципах, мы можем инкапсулировать больше жестов, таких как двойной щелчок, долгое нажатие, смахивание и даже более крутые трехпальцевые и четырехпальцевые. операции с пальцами и т. д. Сделайте приложение более гуманизированным.

Основываясь на вышеуказанном принципе, я инкапсулирую несколько общих инструментов :( ищу звезду -.-)

Советы: поскольку это только для мобильного терминала, его необходимо открыть на мобильном устройстве.demoили включите режим мобильной отладки на ПК!

  1. mtouch.js : библиотека жестов для мобильного терминала, которая инкапсулирует пять вышеупомянутых жестов. Упрощенный дизайн API охватывает стандартные взаимодействия жестов. Его также можно легко расширить на основе этого.
    demo
    github
  2. touchkit.js: на основеmtouchИнкапсулированный уровень — это инструментарий, более близкий к бизнесу, который можно использовать для создания различных жестовых операций, открытия одним щелчком мыши и универсального обслуживания.
    demo
    github
  3. mcanvas.js: экспорт изображений одним щелчком мыши на основе открытого и минималистского API холста.
    demo
    github

Спасибо

Если кто-то попросит вас порекомендовать технические книги по интерфейсу, дайте ему прочитать этот список -> 《Классические технические книги по интерфейсу1 лайк5 Избранное1 Комментарий