Почему перемещение div оставляет след в javascript на телефоне?

На компьютере и iPhone работает нормально, но на Galaxy S3 движущийся блок оставляет след, который случайным образом очищается. Как это исправить?

http://curtastic.com/test7.html

След пропадает (очищается как надо) примерно раз в секунду.

введите здесь описание изображения

<html>
    <head>
        <meta name="viewport" content="width=device-width" />
    </head>
    <body style='margin:0;width:640px;'>
        <div id=fps></div>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script>
            var block;
            var angle=0;

            var fpsFrames = 0;
            var fpsTime = 0;

            function gameLoop() {
                var now = new Date();
                fpsFrames++;
                if (now - fpsTime >= 1000) {
                    $('#fps').html("FPS: "+fpsFrames);
                    fpsFrames = 0;
                    fpsTime = now;
                }

                block.x += 3;
                if (block.x >= $(window).width()-50) {
                    block.x = 0;
                }
                block.canvas.css('left', block.x);
                block.canvas.css('top', block.y);
            }

            $(document).ready(function() {
                $("body").append("<div id=block style='position:absolute;width:33px;height:33px;background:green' class=block></div>")
                block = [];
                block.canvas = $('#block');
                block.x = 0;
                block.y = 55;

                window.requestAnimFrame = (function(){
                  return  window.requestAnimationFrame       ||
                          window.webkitRequestAnimationFrame ||
                          window.mozRequestAnimationFrame    ||
                          function( callback ){
                            window.setTimeout(callback, 1000 / 60);
                          };
                })();


                (function animloop() {
                    requestAnimFrame(animloop);
                    gameLoop();
                })();

            });

        </script>
    </body>
</html>

person Curtis    schedule 15.08.2013    source источник
comment
сделайте ваш setTimeout равным 1000 вместо 1000/60   -  person Paul Nikonowicz    schedule 15.08.2013
comment
@curtis пару вещей .. проверьте ниже   -  person woofmeow    schedule 15.08.2013


Ответы (2)


Вы застряли с телефоном, у которого не так много вычислительной мощности, чтобы так быстро справляться с изменениями.

Есть 2 способа:

  1. Увеличьте время обратного вызова (как указал @Paul) в window.setTimeut, чтобы ваш и другие телефонные браузеры могли работать с javascript. Если это неосуществимо. Тогда попробуй второй.

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

Как сказано в документации

Поскольку фрагмент документа находится в памяти, а не является частью основного дерева DOM, добавление к нему дочерних элементов не вызывает переформатирование страницы (вычисление положения и геометрии элемента). Следовательно, использование фрагментов документа часто приводит к повышению производительности.

Вы также можете проверить мой ответ на этот вопрос, который несколько Связанный.

Надеюсь, это поможет :)

person woofmeow    schedule 15.08.2013
comment
Я ничего не добавляю в DOM во время цикла. Я только меняю css одного div. Также я попытался изменить FPS на 30, и это все еще происходит, но реже. Я хотел бы, чтобы это было плавнее, чем 30 кадров в секунду. У меня много дополнительной мощности процессора, он просто почему-то решил не перерисовывать должным образом. - person Curtis; 15.08.2013
comment
@curtis происходит следующее: когда вы меняете css, браузеру приходится все пересчитывать, а это занимает память. Вместо этого, если вы попытаетесь добавить элементы в dom из domfragment, он не будет выполнять столько вычислений перекомпоновки для макета. Плюсом также является то, что он будет работать более плавно по двум причинам: 1) меньшее количество перекомпоновок и 2) уже будут элементы в памяти (возможно, это неприменимо к вашему случаю, но в любом случае это лучшая стратегия). - person woofmeow; 15.08.2013
comment
Я был ясен? Если нет, вы можете сказать мне .. может быть, я неправильно понял @curtis - person woofmeow; 15.08.2013

Вы пробовали использовать анимацию с ускорением на GPU? Они должны дать вам лучшие результаты, поскольку они фактически привязаны к частоте обновления видеодрайвера. Управление анимацией с помощью JavaScript — не лучший вариант. И другой ответ, вероятно, находится на правильном пути, большинство устройств Android имеют аппаратные недостатки, даже S3, поэтому у вас возникает такая проблема. У меня есть Nexus 7, на котором я что-то тестирую, и часто он просто не справляется с такими простыми задачами, как мои устройства iPad2 и Windows 8 (планшеты и телефоны).

Это может быть разумной статьей для демонстрации различий, http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

person Chris Love    schedule 16.08.2013
comment
Я запускаю его на своем Lumina 920 (Windows Phone), и он отлично работает, кстати. - person Chris Love; 16.08.2013