Правильный способ перехода цвета (или свойства CSS без преобразования/непрозрачности) в Famo.us?

Я пытаюсь заставить квадрат менять цвет при нажатии на Famo.us с переходом. В настоящее время я использую классы CSS:

var square = new Surface({
  size: [200, 200],
  content: 'Hello.',
  properties: {
    lineHeight: '200px',
    textAlign: 'center'
  }
});

square.on('click', function() {
  square.addClass('active');
});

И стиль (написанный в Stylus):

.famous-container
  .famous-surface
    background: rgba(200, 200, 200, 0.5)

    transition: background 0.3s ease

    &.active
      background: rgba(200, 255, 200, 0.5)

Это кажется неправильным, и я не могу использовать такие вещи, как Snap/SpringTransition. Есть ли способ лучше?


person Theodor Vararu    schedule 16.04.2014    source источник


Ответы (2)


Лучшим способом было бы использовать объект RenderController.

RenderController позволяет скрывать и отображать различные визуализируемые элементы с переходом по вашему выбору.

Посмотрите этот пример (слегка измененный для вас), размещенный под учетной записью Famo.us Github.

https://github.com/Famous/examples/blob/master/src/examples/views/RenderController/example.js

var Engine           = require("famous/core/Engine");
var Modifier         = require("famous/core/Modifier");
var Surface          = require("famous/core/Surface");
var RenderController = require("famous/views/RenderController");

var mainContext = Engine.createContext();
var renderController = new RenderController();
var surfaces = [];
var counter = 0;

surfaces.push(new Surface({
     content: "Surface 1",
     size: [200, 200],
     properties: {
         backgroundColor: "green",
         lineHeight: "200px",
         textAlign: 'center'
     }
}));

surfaces.push(new Surface({
     content: "Surface: 2",
     size: [200, 200],
     properties: {
         backgroundColor: "red",
         lineHeight: "200px",
         textAlign: 'center'
     }
}));

renderController.show(surfaces[0]);

Engine.on("click", function() {
    var next = (counter++ + 1) % surfaces.length;
    this.show(surfaces[next]);
}.bind(renderController));

mainContext.add(new Modifier({origin: [.5, .5]})).add(renderController);

Исправлено: добавлены отсутствующие скобки в конце обоих вызовов surface.push(...).

person johntraver    schedule 16.04.2014
comment
Выглядит хорошо на бумаге, мое единственное возражение заключается в том, что если вы используете это для создания нескольких переключаемых кнопок/элементов управления, то вы фактически используете 2-4 поверхности, где обычно была бы только одна. Должны ли известные графические интерфейсы состоять из сотен и сотен поверхностей? (иначе, адекватно ли масштабируется/работает ли этот подход?) - person Theodor Vararu; 17.04.2014
comment
Эй, Теодор. Да, снова из руководств по производительности и ловушек, они упоминают этот случай. Переход значений цвета вызывает большое количество перерисовок и очень неэффективен. Чтобы добиться аналогичного эффекта, попробуйте сложить несколько элементов холста или div разных цветов, а затем соответствующим образом затенить их. famo.us/guides/dev/pitfalls.html - person johntraver; 17.04.2014

Самый простой способ, который я мог придумать, — это обновить backgroundColor с помощью метода setProperties поверхности.

Сделайте это в методе рендеринга Surface, который вызывается при каждом такте рендеринга. Не забудьте вернуть спецификацию рендеринга (идентификатор спецификации).

Вместо использования строк или шестнадцатеричных значений для цветов используйте rgb() или rgba(), которые принимают числовые значения. Числовые значения получаются из объектов Transitionable с помощью метода get.

Переключение числовых значений с помощью метода set Transitionable в обработчике события «щелчок».

Не забудьте передать параметры анимации при установке значения Transitionable (продолжительность и кривая замедления) для плавного анимированного эффекта.

Вот код:

var bgColorRed = new Transitionable(0);
var bgColorGreen = new Transitionable(255);
var bgColorBlue = new Transitionable(0);

var colorTweenTime = 500;

var clicked = false; 

var square = new Surface({
  size: [200, 200],
  content: 'Hello.',
  properties: {
    lineHeight: '200px',
    textAlign: 'center'
  }
});

square.render = function() {
    var red = Math.ceil(bgColorRed.get()),
        green = Math.ceil(bgColorGreen.get()),
        blue = Math.ceil(bgColorBlue.get());

    this.setProperties({
        backgroundColor: 'rgb(' + red + ', ' + green + ', ' + blue + ')'
    });

    return this.id;
};

square.on('click', function() {
    if (clicked) {
        bgColorRed.set(0, { duration: colorTweenTime, curve: 'easeIn' });
        bgColorGreen.set(255, { duration: colorTweenTime, curve: 'easeIn' });
    } else {
        bgColorRed.set(255, { duration: colorTweenTime, curve: 'easeIn' });
        bgColorGreen.set(0, { duration: colorTweenTime, curve: 'easeIn' });
    }
    clicked = !clicked;
});

jsFiddle доступен здесь: http://jsfiddle.net/mcr85/6fx9jo9e/

person macro    schedule 15.09.2014