跨多个视图的Famo.us动画

时间:2015-02-19 01:59:50

标签: javascript css-animations famo.us

我正在玩Famo.us并尝试一些他们的布局和过渡。

我正在尝试构建一组刚刚落到底部的列,然后重新启动并再次降级。偶数和奇数列是不同的颜色,从不同的时间开始看起来很笨拙。

我发现动画很快就会失去同步。有没有办法在一堆视图上使用相同的修饰符。我觉得我的问题是我创建了大量的视图和修改器,然后单独完成所有动画。我想如果我可以使用两个修饰符,他们最好保持同步。

Famo.us版

define('main', function(require, exports, module) {
  var Engine = require('famous/core/Engine');
  var Surface = require('famous/core/Surface');
  var Transform = require('famous/core/Transform');
  var StateModifier = require('famous/modifiers/StateModifier');
  var GridLayout = require("famous/views/GridLayout");
  var el = document.getElementById('famous-app');
  var View = require('famous/core/View');
  var Modifier = require('famous/core/Modifier');

  surfaceCount = 550;
  width = parseInt($('#famous-app').width());

  boxSize = width / surfaceCount;

  var mainContext = Engine.createContext(el);

  var grid = new GridLayout({
    dimensions: [surfaceCount, 1]
  })

  var views = [];
  var modifiers = [];
  
  grid.sequenceFrom(views);

  for (var i = 0; i < surfaceCount; i++) {

    var stateModifier = new StateModifier();
    var view = new View();
    var color;

    // Set Even Bars to be blue
    if (parseInt(i) % 2 == 0) {
      color = "blue";
    } 
    // Set Odd Bars to be Green
    else {
      color = "green";
    }
 
    // Create the Surface
    var surface = new Surface({
      size: [boxSize, 300],
      properties: {
        color: color,
        textAlign: 'center',
        backgroundColor: color
      }
    });

    // Add the Surface and its unique Modifier to the View
    view.add(stateModifier).add(surface);

    // Create an array of all Views and thier Modifiers
    modifiers.push(stateModifier);
    views.push(view);
  }

  mainContext.add(grid);

  // Set up the loop to do the animation
  var setup = function() {

    // Go through and start all the bars at the top
    for (var index = 0; index < modifiers.length; index++) {
      modifiers[index].setTransform(
        Transform.translate(0, -300, 0))

    }

    // Start the animation on the odd bars after 500 ms delay.
    window.setTimeout(function() {
      for (var index = 1; index < modifiers.length; index += 2) {
        transform(modifiers[index], 0);

      }
    }, 500);

    // Start the animation on the even bars
    for (var index = 0; index < modifiers.length; index += 2) {
      transform(modifiers[index]);

    }
  }

  // Do the actual transform, when finished repeat
  var transform = function(modifier) {

    modifier.setTransform(
      // Slide bar down over one second
      Transform.translate(0, 300, 0), {
        duration: 1000,
        curve: 'linear'
      },
      function() {
        modifier.setTransform(
          // Move Bar back to starting position
          Transform.translate(0, -300, 0), {
            duration: 0,
            curve: 'linear'
          },
          function() {
            // Repeat
            transform(modifier);
          });

      });
  }

  setup();

});

require(['main']);
.testing-containers {
  height: 600px;
}
.test-container {
  height: 300px;
  overflow: hidden;
  margin: 24px 0;
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.4/famous.css" />

<script src="http://code.famo.us/famous/0.3.4/famous.min.js"></script>



<div class="test-container">
  <div id="famous-app" style="overflow:hidden;"></div>
</div>

2 个答案:

答案 0 :(得分:1)

转换的时间取决于渲染时间,并且即使它们同时启动,也会等待引擎在下一个刻度上呈现项目时不同步。

为您的奇数列转换使用一个修饰符,为偶数列转换使用一个修饰符。将两个修饰符添加到同一级别的上下文中,并创建奇数和偶数节点。

  var oddModifier = new StateModifier({
    transform: Transform.translate(0, -300, 0)
  });
  var evenModifier = new StateModifier({
    transform: Transform.translate(0, -300, 0)
  });

  var rootNodeOdd = mainContext.add(oddModifier);
  var rootNodeEven = mainContext.add(evenModifier);

每列仍需要修饰符,因为您需要沿y轴位于不同位置。修改器仍将添加到每个列的视图中。这取代了必须使用GridLayout

    if (parseInt(i) % 2 === 0) {
      rootNodeOdd.add(view);
      color = "blue";
    }
    // Set Odd Bars to be Green
    else {
      rootNodeEven.add(view);
      color = "green";
    }

启动过渡循环以设置奇数和偶数修饰符的变换。

  var setupEven = function() {
    oddModifier.running = true;
    evenModifier.setTransform(
      // Slide bar down over one second
      Transform.translate(0, 300, 0), {
        duration: 1000,
        curve: 'linear'
      },
      function() {
        evenModifier.setTransform(
          // Move Bar back to starting position
          Transform.translate(0, -300, 0), {
            duration: 0,
            curve: 'linear'
          },
          function() {
            evenModifier.running = false;
            setup();
          }
        );

      });
  };
  var setupOdd = function() {
    oddModifier.running = true;
    oddModifier.setTransform(
      // Slide bar down over one second
      Transform.translate(0, 300, 0), {
        duration: 1000,
        curve: 'linear'
      },
      function() {
        oddModifier.setTransform(
          // Move Bar back to starting position
          Transform.translate(0, -300, 0), {
            duration: 0,
            curve: 'linear'
          },
          function() {
            oddModifier.running = false;
            setup();
          }

        );

      });
  };

  var setup = function() {
    if (!oddModifier.running && !evenModifier.running) {
      setupEven();
      Timer.setTimeout(setupOdd, 500);
    }
  }

  setup();

注意:使用Famo.us中的Timer.setTimeout实用程序而不是window.setTimeout。在这种情况下,现在不需要网格。

&#13;
&#13;
define('main', function(require, exports, module) {
  var Engine = require('famous/core/Engine');
  var Surface = require('famous/core/Surface');
  var Transform = require('famous/core/Transform');
  var StateModifier = require('famous/modifiers/StateModifier');
  var GridLayout = require("famous/views/GridLayout");
  var View = require('famous/core/View');
  var Modifier = require('famous/core/Modifier');
  var Timer = require('famous/utilities/Timer');

  surfaceCount = 550;
  var el = document.getElementById('famous-app');
  width = parseInt($('#famous-app').width());

  boxSize = width / surfaceCount;

  var mainContext = Engine.createContext(el);

  var modifiers = [];

  var oddModifier = new StateModifier({
    transform: Transform.translate(0, -300, 0)
  });
  var evenModifier = new StateModifier({
    transform: Transform.translate(0, -300, 0)
  });

  var rootNodeOdd = mainContext.add(oddModifier);
  var rootNodeEven = mainContext.add(evenModifier);

  for (var i = 0; i < surfaceCount; i++) {

    var stateModifier = new StateModifier();
    var view = new View();
    var color;

    // Set Even Bars to be blue
    if (parseInt(i) % 2 === 0) {
      rootNodeOdd.add(view);
      color = "blue";
    }
    // Set Odd Bars to be Green
    else {
      rootNodeEven.add(view);
      color = "green";
    }

    // Create the Surface
    var surface = new Surface({
      size: [boxSize, 300],
      properties: {
        color: color,
        textAlign: 'center',
        backgroundColor: color
      }
    });

    // Add the Surface and its unique Modifier to the View
    view.add(stateModifier).add(surface);

    stateModifier.setTransform(Transform.translate(i * boxSize, 0, 0));

    // Create an array of all Views and thier Modifiers
    modifiers.push(stateModifier);
  }

  // Set up the loop to do the animation
  var setupEven = function() {
    oddModifier.running = true;
    evenModifier.setTransform(
      // Slide bar down over one second
      Transform.translate(0, 300, 0), {
        duration: 1000,
        curve: 'linear'
      },
      function() {
        evenModifier.setTransform(
          // Move Bar back to starting position
          Transform.translate(0, -300, 0), {
            duration: 0,
            curve: 'linear'
          },
          function() {
            evenModifier.running = false;
            setup();
          }
        );

      });
  };
  var setupOdd = function() {
    oddModifier.running = true;
    oddModifier.setTransform(
      // Slide bar down over one second
      Transform.translate(0, 300, 0), {
        duration: 1000,
        curve: 'linear'
      },
      function() {
        oddModifier.setTransform(
          // Move Bar back to starting position
          Transform.translate(0, -300, 0), {
            duration: 0,
            curve: 'linear'
          },
          function() {
            oddModifier.running = false;
            setup();
          }

        );

      });
  };

  var setup = function() {
    if (!oddModifier.running && !evenModifier.running) {
      setupEven();
      Timer.setTimeout(setupOdd, 500);
    }
  }

  setup();

});

require(['main']);
&#13;
.testing-containers {
  height: 600px;
}
.test-container {
  height: 300px;
  overflow: hidden;
  margin: 24px 0;
  position: relative;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />

<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>



<div class="test-container">
  <div id="famous-app"></div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

你对修饰语的直觉是正确的。让所有这些表面与共享修饰符一起移动比使用回调和setTimeout使它们全部保持同步更可靠。

然而,对于像gridLayout这样的东西,这变得很困难,因为布局序列中没有一个表面可以共享修饰符。

有很多方法可以解决这个问题。我使用两个gridLayouts制作了一个解决方案。希望它有所帮助!

Famous.loaded(function () {
var Engine = Famous.Core.Engine;
var Modifier = Famous.Core.Modifier;
var Transform = Famous.Core.Transform;
var Surface = Famous.Core.Surface;
var GridLayout = Famous.Views.GridLayout;
var Timer = Famous.Utilities.Timer;

var ctx = Engine.createContext();
var ctxSize = ctx.getSize();
var numSurfaces = 16;

/*
    CREATE PINK GRID
*/
var pinkGrid = new GridLayout({
    dimensions: [numSurfaces, 1],
});
var pinkGridMod = new Modifier({ size: [undefined, 220]});

/*
    CREATE RED GRID
*/
var redGrid = new GridLayout({
    dimensions: [numSurfaces, 1],
});
var redGridMod = new Modifier({
    size: [undefined, 220],
    transform: Transform.translate(0, 0, 0)
});

/*
    CREATE SURFACES
*/
var redSurfaces = [];
var pinkSurfaces = [];
for (var i = 0; i < numSurfaces; i++) {
    var input = i % 2 ? pinkSurfaces : redSurfaces;
    input[i] = new Surface({
        properties: {
            backgroundColor: i % 2 ? 'pink' : 'red'
        }
    });
}
pinkGrid.sequenceFrom(pinkSurfaces);
redGrid.sequenceFrom(redSurfaces);

/*
    ANIMATE
*/

Timer.every(function() { 
    pinkGridMod.setTransform(Transform.translate(0, 0, 0));
    pinkGridMod.setTransform(Transform.translate(0, ctxSize[1], 0), { duration: 1000 })
}, 100);

Timer.after(function() {
    Timer.every(function() {
        redGridMod.setTransform(Transform.translate(0, 0, 0));
        redGridMod.setTransform(Transform.translate(0, ctxSize[1], 0), { duration: 1000 })
    }, 100);
}, 50)

/*
    ADD GRIDS TO CONTEXT
*/

    ctx.add(pinkGridMod).add(pinkGrid);
    ctx.add(redGridMod).add(redGrid);
});

在这里查看JSFiddle - &gt; http://jsfiddle.net/z1kz5ndf/