Safari и requestAnimationFrame получают DOMHighResTimestamp; окно.производительность недоступна

Я создал анимацию, используя requestAnimationFrame. Отлично работает в Windows Chrome и IE; Safari (проверено Safari 6 и 7) ломается. Оказывается, rAF получает временную метку DOMHighResTimestamp, а не Date. Это все прекрасно и хорошо, чего я и ожидал, так как теперь это часть спецификации. Однако, насколько мне удалось найти, нет никакого способа получить текущий DOMHighResTimestamp (т.е. window.performance недоступен, даже с префиксом). Таким образом, если я создаю время начала как временную метку Date, оно ведет себя совершенно неправильно, когда я пытаюсь определить прогресс в обратном вызове rAF (очень маленькие отрицательные числа).

Если вы посмотрите на этот JSBin в Safari, он вообще не будет анимироваться.

В этом JBin я сделал изменение, чтобы "пропустить" первый кадр (где time параметр равен undefined), так что startTime устанавливается на параметр time в следующем кадре. Кажется, работает, но пропуск кадра кажется немного дрянным.

Есть ли способ получить текущий DOMHighResTimestamp в Safari, учитывая отсутствие window.performance? Или, наоборот, принудительно перевести rAF в какой-то устаревший режим, который заставит его вместо этого получать отметку даты и времени?

Кто-нибудь знает, почему в Safari такое несоответствие, когда он предоставляет параметр в формате, который вы не можете получить каким-либо другим способом?


person Turner Hayes    schedule 25.04.2014    source источник


Ответы (1)


На данный момент Performance.now() является только рекомендацией. https://developer.mozilla.org/en-US/docs/Web/API/Performance.now%28%29 Я могу только предположить, что это вопрос времени, прежде чем он станет официальным, учитывая, что он встроен во все, кроме Safari.

Кроме того, используйте этот факт в своих интересах. Поскольку вы знаете, что requestAnimationFrame возвращает DOMHighResTimestamp, используйте его для своего времени.

Game.start = function(timestamp){
    if(timestamp){
        this.time = timestamp;
        requestAnimationFrame(Game.loop);
    }else{
        requestAnimationFrame(Game.start);
    }
}

Game.loop = function(timestamp){
    Game.tick(timestamp);
    ... your code
    requestAnimationFrame(Game.loop);
}

Game.tick = function(timestamp) {
    this.delta      = timestamp - this.time;
    this.time       = timestamp;
};

Что я здесь делаю, так это вызываю Game.start, который запускает цикл (я сталкивался с ситуациями, когда отметка времени была неопределенной, поэтому мы пытаемся, пока не получим что-то действительное). Как только мы получаем, что у нас есть наше базовое время, и поскольку RAF собирается возвращать метку времени, наша функция тика никогда не должна вызывать Date.now или performance.now, пока мы передаем ей метку времени, возвращенную requestAnimationFrame.

person ericjbasti    schedule 26.04.2014
comment
Это похоже на тот же подход, что и мой второй JSBin — отбросить первый кадр и начать анимацию со второго кадра. Это работает, но на самом деле не отвечает на мой вопрос, почему Safari не предоставляет никакого доступа к DOMHighResTimestamp за пределами rAF. - person Turner Hayes; 27.04.2014
comment
Это просто то, что они не реализовали. Я уверен, что в какой-то момент они это сделают, но пока сохраните себе вычисления и используйте тот, который вам передали. - person ericjbasti; 27.04.2014
comment
Так что я ничего не упускаю — они действительно не предоставляют доступ к DOMHighResTimestamp вне обратного вызова rAF? - person Turner Hayes; 05.05.2014
comment
Поэтому я еще немного покопался, чтобы проверить. Нашел это webkit.org/blog/2188/, если вы прочитаете последний абзац, вы подумаете, что префикс поставщика для window.performance.now() был удален. означало бы, что вы можете использовать его в Safari. Однако во всей другой документации указано, что объект производительности не существует в Safari, и я могу убедиться, что его нет в последней версии Safari. - person ericjbasti; 06.05.2014
comment
Интересно. Хорошая находка — похоже, Safari нам лжет! - person Turner Hayes; 10.05.2014
comment
caniuse.com/#search=performance сообщает, что в Safari 8 и 9 есть поддержка window.performance .now(), но я только сегодня обновился с Safari 7 до Safari 9 (в Mavericks, MacBook Pro 2010) и большое разочарование: window.performance не определено! - person Timo Kähkönen; 04.10.2015
comment
@ Тимо очень интересно. Я только что попробовал это в Safari 9 на El Capitan, и window.performance.now() работает. Вы бы не подумали, что это будет связано с ОС, но похоже, что это может иметь место. - person ericjbasti; 04.10.2015