TremulaJS是一款非常酷的跨设备多功能的无限循环js轮播图插件。TremulaJS是一个客户端javascript UI组件,它基于贝兹曲线和物理动量效应制作各种效果,可以制作无限循环的图片流,图片瀑布流,旋转木马特效等。TremulaJS适用于桌面和移动触摸设备。

TremulaJS由5个部分组成:滚动轴(Scroll Axis)、动量循环(Momentum Loop)、内容网格(Content Grid)、内容模型(Content Box)和网格投影(Grid Projection)。

滚动轴

TremulaJS可以制作各种视觉效果,但是它可以在两个方向上滚动,这些值封装在 Scroll Axis 对象中,该对象用于管理水平和垂直方向上的滚动。

动量循环

动量循环(momentum loop)用于调节系统的动量值。它是各种子组件输出的总和,包括:一个内部时钟的动量,各种条件控制功能与滚动轴状态和用户交互事件处理程序。在每一个动画帧它都会返回一个瞬时的动量值,用于计算滚动偏移的位置。

内容网格

内容网格是一个可配置的XY网格抽象模型的虚拟内容模型。所有添加到网格中的内容都会沿十字轴坐标系按比例缩放,以便于管理行或列的坐标。

在每一个动画帧,动量移动沿十字轴移动到一个新的位置,内容网格会使用一个新的相对位置来更新它的子内容模型。

内容模型

内容模型用于为内容网格添加内容。内容模型有宽度,高度和一个可选的HTML模板,以及一个图片占位。

每一个内容块也保持各种原始波形值对应于它自己的屏幕上滚动的进程。这些波形值可以映射出一个内容模型DOM元素在时间和空间上的任何动画状态。

内容模型的波形值

在上图中,一个牛肉块从屏幕的左边移动到右边,它的每一个位置都对应一个梯度波形值,我们可以使用一个函数来映射它,在函数中使用CSS translateX()属性来更新每一个运动状态的值。

然而上面所说的并不是默认的行为,默认的行为要更复杂一些。下面是一个在内容模型的一个动画周期内调用的默认函数的简单代码:

function updateContentBoxElementProperites(x,y) {
  var ramp = this.waveforms.headRamp,
    xo=x,
    yo=y,
    zo=0;
    
  this.e.style.transform = 'translate3d(' + xo + 'px,' + yo +'px, ' + zo + 'px)';
  //this.e.style.opacity = ramp;
  this.pPos = [x,y];//cache the current position in the Content Box model
}                
              

这个函数会在内容模型改变位置的时候被调用,它传入了新的坐标系。X和Y都是绝对定位的,这些值是给内容网格使用,它们带有内容块的信息,它们能处理所有网格上内容模型的所有位置信息。上面的函数会在每一个动画帧中每一个内容模型中调用。

网格投影

延续上边的例子,内容模型函数会在每一个动画帧中被执行。这个函数会传入瞬时的X和Y坐标值,另外,它还会为滚动线程传入一些原始的波形值,这时候,我们可以为它映射任意的贝兹曲线和CSS属性。接着上边的例子,我们要使用贝兹曲线来沿垂直方向移动内容模型的位置。

内容模型的贝兹曲线

var bezierArcPath = [
  {x:0,y:0},
  {x:0,y:1},
  {x:1,y:1},
  {x:1,y:0}
];

function updateContentBoxElementProperites(x,y,env) {

  var path = bezierArcPath;

  var 
    areaX = env.viewDims[0],
    areaY = env.viewDims[1],
    ramp = this.waveforms.tailRamp,
    xo=x,
    yo=y,
    zo=0;

  var xyFactor = [
    areaX,
    areaY
  ];

  var scaledPath = env.factorPathBy(path,xyFactor);
  
  var p = jsBezier.pointOnCurve(cubicBezier, ramp);
  var g = jsBezier.gradientAtPoint(cubicBezier, ramp);
  
  xo = p.x - (this.dims[0]*.5);
  yo = areaY - p.y - (this.dims[1]*.5);
  zo = 0;

  this.e.style.transform = 'translate3d(' + xo + 'px,' + yo +'px, ' + zo + 'px)';

  this.pPos = [x,y];
}                
              

在这个例子中使用了一些额外的方法来实现贝兹曲线效果。首先观察env.factorPathBy(path,xyFactor),它允许我们创建弹性内容区域(内容拖到容器边界时的回弹效果),并且在两个方向上缩放内容以适应模型的大小。它将返回一个可使用的坐标系。

接下来是jsBezier.pointOnCurve(cubicBezier, ramp),它使用贝兹曲线和斜坡输出值作为参数。它会返回转换后的X和Y值。

想要了解更多关于该js轮播图插件的信息,可以参考:https://github.com/garris/TremulaJS