Анимация в famu.us

Пример анимации в famo.us js

18 July 2014 г. 14:01:20

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

Как всегда исходный код приложения можно найти на гитхабе, а финальный пример доступен тут, где можно нажать мышкой в любом месте и насладиться анимацией от famo.us ))

Объединение модификаторов

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

mainContext.add(модификатор_1).add(модификатор_2).add(модификатор_n).add(поверхность)

Попробуем нарисовать куб, но без верхней и нижней грани, пока они не нужны. при отрисовки каждой поверхности. Например правую поверхность надо повернуть на 90 и переместить на половину длинны вправо. В прошлой статье было описано как это можно сделать при помощи двух модификаторов, это действительно так, однако в famo.us есть возможность объединять модификаторы. Это делается при помощи модификатора Transform.multiply. В качестве аргументов он принимает 2 модификатора и объединяет трансформацию в первом модификаторе и втором.

createSurface({
  modifier: {transform : Transform.multiply(Transform.translate(DEFAULT_WIDTH / 2, 0, 0),Transform.rotateY(Math.PI/2) ) }
});

аналогичным образом образом можно выполнить трансформации для остальных поверхностей

createSurface({
  modifier: {transform : Transform.translate(0, 0, DEFAULT_WIDTH / 2)}
});
createSurface({
  modifier: {transform : Transform.multiply(Transform.translate(DEFAULT_WIDTH / 2, 0, 0),Transform.rotateY(Math.PI/2) ) }
});
createSurface({
  modifier: {transform : Transform.multiply(Transform.translate(0, 0, -DEFAULT_WIDTH / 2),Transform.rotateY(Math.PI) )  }
});
createSurface({
  modifier: {transform : Transform.multiply( Transform.translate(-DEFAULT_WIDTH / 2, 0, 0), Transform.rotateY(-Math.PI/2) ) }
});

Вывод трехмерных объектов при помощи famo.us

Объединение поверхностей в общий объект

Каждая поверхность выводится в отдельности, и чтобы куб при дальнейших модификациях вел себя как единое целое, надо применять модификаторы к каждой грани. Это очень неудобно. Можно ли объединить несколько граней в отдельный объект, чтобы все последующие модификаторы применялись ко всем поверхностям внутри этого объекта. К счастью при помощи famo.us вы легко можете объединить несколько поверхностей в объект при помощи объекта RenderNode. Импортировать его можно следующим образом:

var RenderNode = require('famous/core/RenderNode');

создадим экземпляр этого класса

var box = new RenderNode();

Далее мы можем добавлять поверхности точно так-же как поверхности и модификаторы добавлялись в контекст.

var createSurface = function(param){
  var surface =  new Surface({
    size: [DEFAULT_WIDTH,DEFAULT_HEIGH],
    properties:{
      backgroundColor: "gray",
      cssText: "background: radial-gradient(#eee 10%, #ddd 60%, #bbb)",
      overflow: "auto"
    }
  });

  var modifier = new Modifier(param.modifier);
  box.add(modifier).add(surface)
}

В famo.us нет источников света, поэтому если просто выводить поверхности они будут выглядеть плоскими. Это можно исправить добавив на поверхности градиент cssText: "background: radial-gradient(#eee 10%, #ddd 60%, #bbb)" .

Далее box добавляется в контекст:

mainContext.add(cube.box);

Анимация

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

  Engine.on('click', function(){
    cube.angle += 90;
    cube.animate.setTransform(
      Transform.multiply(Transform.translate(0, 0, -1000), Transform.rotateY(cube.angle / 180 * Math.PI)),
      {duration: 1500, curve: Easing.inOutBack}
    );
    cube.animate.setTransform(
      Transform.multiply(Transform.translate(0, 0, 0), Transform.rotateY(cube.angle / 180 * Math.PI)),
      {duration: 500, curve: Easing.inOutBack}
    );
  })

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

Таким образом у нас получился достаточно красивый эффект, а исходный код легко помещается на один экран. И здесь открывается большой простор для фантазии. Стоит отметить что благодаря стилю overflow: "auto у каждой поверхности появляется свой собственный скролбар, он работает даже во время анимации. И играть с параметрами достаточно интересно

Немного диванной аналитики

Подведем небольшой итог и проверим работоспособность в разных браузерах и на разных платформах. Famo.us заявляет что при помощи их фреймоврка можно добиться 60 fps. Как показывают тесты это не совсем так.

Тестировать я буду на своем слабеньком рабочем компьютере четырех-ядерном процессоре i5 3.33 ГГц. В моем приложении всего 4 поверхности и достаточно простая анимация и в хроме все работает как надо, анимация плавная и все красиво, в момент анимации CPU подскакивает до 10%. Далее я проверил IE 11, в нем для работы приложения требуется включить ActiveX, если запретить, то работать не будет однако если его включить то все работает не хуже чем в хроме однако CPU в момент анимации подпрыгивает до 17% что мне кажется слишком, для такого простого приложения. Теперь посмотрим как будет выглядеть в фаерфоксе. По моим ощущениям в фаерфорксе анимация выглядит хуже всего, никакими 60fps не пахнет даже близко, анимация получается очень рваной, и при этом он потребяет 25% CPU, т.е фактически все cpu одного ядра.

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


Оставьте свой комментарий

comments powered by Disqus
Меню

Cult of digits 2014 Яндекс.Метрика