Подтвердить что ты не робот

Оптимизация спрайтов на основе SVG для ускорения графического ускорения CSS3 HW в (мобильном) браузере

На прошлой неделе я помогал другу экспериментировать с листами спрайтов на основе SVG в браузере. Мы хотели придумать идеальный рабочий процесс для подготовки, публикации и запуска высококачественной анимированной графики в браузере. Поэтому в идеале есть один источник данных анимации, который будет работать на небольших экранах смартфонов, планшетах, сетчатых дисплеях и настольных браузерах.

В теории, SVG (на основе вектора) должен быть идеальным для этого, но поскольку SVG обычно не используется так часто, мы решили проверить его. Идея заключалась в том, чтобы не использовать SMIL SVG (так что без анимации на основе SVG), а вместо этого создать анимационный спрайт-лист (как обычно, с растровыми данными PNG/JPG), но делать это с помощью чистых векторов, то есть SVG. Это было немного больше, но если это сработает, это будет работать даже с чем-то еще более оптимизированным.

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

Во всяком случае, результат работает на удивление хорошо, но также терпит неудачу в некоторых областях (обратите внимание, что в тестовых целях мы работали только с браузерами на основе Webkit, т.е. Safari, Chrome, мобильным Safari на iOS и Android ICS).

В CSS довольно легко вызвать аппаратное ускорение для листа спрайта, подобного этому (по крайней мере, в современных браузерах с ключевыми кадрами и шагами) - вы просто это делаете:

background-image: url(my.svg);
-webkit-animation: walk 1s steps(12, end) infinite; 

для вызова анимации на основе ключевого кадра, показанной здесь:

@-webkit-keyframes walk {
    from { -webkit-transform: translate3d(0, 0, 0); }
    to { -webkit-transform: translate3d(-100%, 0, 0); }          
}

где использование translate3d должно позволить GPU заходить, и все это должно быть аппаратно ускорено в iOS-мобильном браузере Safari и Android ICS.

Удивительно, учитывая, что это своего рода метод грубой силы и довольно большая векторная анимация (600x600px для теста) - все это летает. Но он не идеален - он мерцает в Сафари перед взлетом. И в браузере ICS все это время мерцает, поэтому его нельзя использовать.

Итак, мы попробовали обычные трюки, чтобы избавиться от мерцания, например:

-webkit-transform: translateZ(0);    
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;

Но это не сработало. Итак, мы попытались растрировать SVG динамически в памяти и использовать его как текстуру с -webkit-transform: scale3d (1, 1, 0), но это не помогло эфиру.

Наконец, мы просто заменили SVG визуализированным листом спрайта PNG/JPG того же размера, думая, что сложные векторы слишком много для браузера - но угадайте, что? Это одна и та же проблема, поэтому вообще не SVG-рендеринг - проблема с рисунком браузера. Еще одно доказательство этого - если мы замедляем анимацию до 1FPS, мерцание все еще сохраняется.

Является ли изображение слишком большим для GPU? Достигли ли мы предела производительности того, что вы можете удобно рисовать/анимировать в браузере (в частности, в мобильном телефоне)?

Мне бы очень понравились идеи/хаки о том, как потенциально избавиться от мерцания (тем более, что он быстро выполняет sooo). Его просто многообещающий метод - анимация браузера с высокой производительностью, которая адаптируется к разным размерам экрана - HTML5 Holy Grail;)

С помощью нескольких оптимизаций, таких как

<svg preserveAspectRatio="xMinYMax slice" viewBox="0 0 600 50">

и некоторые магии CSS мы можем настроить SVG на свой контейнер и изменить его размер с одного класса CSS. Это действительно будет творить чудеса - но, увы, мерцание.

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

4b9b3361

Ответ 1

Довольно крутая идея.

Как насчет изменения zindex фреймов, чтобы вы отображали изображения друг над другом? Это может решить мерцание, потому что во время перерисовки последний кадр все еще виден. Таким образом, вы просто увеличиваете значение zindex последнего кадра. Конечно, для этого есть предел, и вам понадобится reset zindex снова, но это может сильно повлиять на сокращение мерцания.

Ответ 2

У меня нет ICS, чтобы проверить это, но на iOS 6 на iPhone 5 и Jelly Bean 4.1.1 на Galaxy Nexus анимация выглядит довольно гладко, за исключением случаев, когда я увеличиваю масштаб, и в этот момент я получить несколько фликкерских кадров, а затем снова опуститься.

Это напомнило мне аналогичную проблему, которую я получал на большом холсте и трансформировал его по экрану (с большинством холста за кадром в любой момент времени).

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

Мое "решение" было для -webkit-transform: масштабировать все изображение до достаточно малого, чтобы гарантировать, что все это подходит на экране (так что браузер не имеет другого выбора, кроме как сделать весь образ), пусть он будет рендерить, а затем масштабирует его до размера, который я хотел.

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

Мне было бы очень интересно узнать, подходит ли вам подобная техника.