Датчик ориентации устройства для преобразования CSS - PullRequest
2 голосов
/ 18 июня 2019

Я создал следующий виджет (см. Демонстрацию здесь) , чтобы имитировать вкладку датчиков на вкладке разработчика Chrome:


enter image description here


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

let phone = document.querySelector(".phone");
    window.addEventListener('deviceorientation', (event) => {
      phone.style.transform =
        "rotateY(" + ( event.alpha) + "deg) "
        +
        "rotateX(" + (90 - event.beta) + "deg) "
        +
        "rotateZ(" + (event.gamma ) + "deg)";
    })

Однако, если я поиграюхватит со значениями, мой виджет и хромовый виджет не синхронизируются.Очевидно, мои расчеты неверны, что мне не хватает?

Чтобы проверить мой код, просто перейдите на demo , откройте вкладку датчиков инструментов разработчика и поиграйтесь с виджетом.

Любая помощь приветствуется.

Обновление: для перехода на вкладку датчиков: Откройте инструменты разработчика, нажмите Esc, на второй панели нажмите 3 точки слева и выберите датчики.

Обновление: Пример проблемных значений:
альфа: -77.6163
бета: -173.4458
гамма: -40.4889

1 Ответ

2 голосов
/ 18 июня 2019

Вот как это делается в хроме и хроме:

codepen

Существенная часть состоит в том, что когда мы применяем gamma преобразование угла, осьуже повернут предыдущим beta преобразованием угла.Поэтому нам нужно применить угол поворота гаммы не к оси (0, 0, 1), а к преобразованной оси, которая учитывает угол бета.

Источник:

function degreesToRadians (deg) {
    return deg * Math.PI / 180;
}

class EulerAngles {
  constructor(alpha, beta, gamma) {
    this.alpha = alpha;
    this.beta = beta;
    this.gamma = gamma;
  }
  
  toRotate3DString() {
    const gammaAxisY = -Math.sin(degreesToRadians(this.beta));
    const gammaAxisZ = Math.cos(degreesToRadians(this.beta));
    const axis = {
      alpha: [0, 1, 0],
      beta: [-1, 0, 0],
      gamma: [0, gammaAxisY, gammaAxisZ]
    };
    return (
      "rotate3d(" +
      axis.alpha.join(",") +
      "," +
      this.alpha +
      "deg) " +
      "rotate3d(" +
      axis.beta.join(",") +
      "," +
      this.beta +
      "deg) " +
      "rotate3d(" +
      axis.gamma.join(",") +
      "," +
      this.gamma +
      "deg)"
    );
  }
}

function ready(fn) {
  if (
    document.attachEvent
      ? document.readyState === "complete"
      : document.readyState !== "loading"
  ) {
    fn();
  } else {
    document.addEventListener("DOMContentLoaded", fn);
  }
}

ready(() => {
  let phone = document.querySelector(".phone");
  window.addEventListener("deviceorientation", event => {
    console.log(event);
    const eulerAngles = new EulerAngles(event.alpha, -90 + event.beta, event.gamma)
    phone.style.transform = eulerAngles.toRotate3DString();
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...