javascript - 用于生成动画效果序列的算法

标签 javascript algorithm

前言

我正在实现一个提供文本淡入淡出效果的 jQuery 插件 [demo] 。这些效果是通过基于字符索引序列的字符替换获得的。

例如,有这个文本(11 个字符 x 9 行 = 99 个字符):

var text = 
  "0123456789\n"+
  "0123456789\n"+
  "0123456789\n"+
  "0123456789\n"+
  "0123456789\n"+
  "0123456789\n"+
  "0123456789\n"+
  "0123456789\n"+
  "0123456789\n"

这个顺序导致了一个从左到右从上到下的渐变效果 [fiddle] :

var sequence =      
  [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10 ,
   11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 ,
   22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 ,
   33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43 ,
   44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54 ,
   55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65 ,
   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76 ,
   77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87 ,
   88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 ]

生成这个序列很容易:

var textToSequence = function(text) {
  for (var s = [], i = 0; i < text.length; i++) s.push(i)
  return s
}
var sequence = textToSequence(text)

问题

我想添加一个 顺时针从外到内 45° 扭曲螺旋 效果(不,这不是极端俯冲类型的名称 :P )。这是上面 text 的正确顺序:

var sequence =
  [ 0,                  10,                 98,              88,
    11, 1,              9, 21,              87, 97,          89, 77,
    22, 12, 2,          8, 20, 32,          76, 86, 96,      90, 78, 66,
    33, 23, 13, 3,      7, 19, 31, 43,      65, 75, 85, 95,  91, 79, 67, 55,
    44, 34, 24, 14, 4,  6, 18, 30, 42, 54,  64, 74, 84, 94,  92, 80, 68, 56,
    45, 35, 25, 15, 5,  17, 29, 41, 53,     63, 73, 83, 93,  81, 69, 57,
    46, 36, 26, 16,     28, 40, 52,         62, 72, 82,      70, 58,
    47, 37, 27,         39, 51,             61, 71,          59,
    48,                 38,                 50,              60,
    49 ]

你可以在这里看到生成的动画 [fiddle]

现在:我想不出任何生成上述序列的算法。有什么建议吗?

奖励积分(和很多尊重!)如果你能为它的变体推荐算法:

  • 顺时针从内到外
  • 逆时针从外到内
  • 逆时针从内到外

最佳答案

Here 就是你想要的。

我用四个 Angular 填充一个菱形。

每个 for 循环 绘制一条包含 n 项的 45° 线,n 是我们进行的转弯次数。

为了简单起见,我制作了一个 convert 函数,它将当前项目的 (x, y) 位置转换为索引。

如果之前没有添加索引,我只会添加索引(以处理 Angular 重叠的最后情况)。

我想您现在可以轻松获得奖励积分了。

// add item if not present in the array
function pushIfNotPresent(array, item)
{
    if (array.indexOf(item)==-1)
        array.push(item);
}

// convert x y position to index
function convert(x, y, width)
{
    return y*width+x;
}


$(document).ready(function() {
    var text = 
      "0123456789\n"+
      "0123456789\n"+
      "0123456789\n"+
      "0123456789\n"+
      "0123456789\n"+
      "0123456789\n"+
      "0123456789\n"+
      "0123456789\n"+
      "0123456789\n"

    var sequence2 = [];

    var width = 10;
    var height = 9;

    var n=0;

    while(sequence2.length<text.length)
    {
        // top left corner
        for(var i=0 ; i<=n && sequence2.length<text.length ; i++)
        {
            console.log(i);
            pushIfNotPresent(sequence2, convert(i, n-i, width+1)); 
        }
        // top right corner
        for(var i=0 ; i<=n && sequence2.length<text.length ; i++)
        {
            pushIfNotPresent(sequence2, convert(width-1-n+i, i, width+1)); 
        }
        // bottom right corner
        for(var i=0 ; i<=n && sequence2.length<text.length ; i++)
        {
            pushIfNotPresent(sequence2, convert(width-1-i, height-1-n+i, width+1)); 
        }
        // bottom left corner
        for(var i=0 ; i<=n && sequence2.length<text.length ; i++)
        {
            pushIfNotPresent(sequence2, convert(n-i, height-1-i, width+1)); 
        }

        n++;
    }

    // real spiral
    width = 10;
    var sequence3 = [];
    var angle = 0.0;
    var center = (width-1)/2.0;
    var radius = (width+3)/2.0;
    var i=0;
    while(sequence3.length<text.length && i<10000)
    {
        angle += 2.0*3.1416*1.0/360;
        radius -= 0.001;
        pushIfNotPresent(sequence3, convert(center+radius*Math.cos(angle), center+radius*Math.sin(angle), width+1)); 
        i++;
    }

    $('#test01i').textFadeIn( { 'text': text, 'milliseconds': 50, 'sequence': sequence2 })
    $('#test01o').textFadeOut({ 'text': text, 'milliseconds': 50, 'sequence': sequence2 })
})

请注意,我在一个 for 循环中使用 cos 和 sin 函数添加了一个真正的螺旋效果(尝试序列 3)...

关于javascript - 用于生成动画效果序列的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23810474/

相关文章:

javascript - 在我的 SharePoint 2010 Web 部件中查找一个 div

php - 这是 'better way' 的做法吗?

algorithm - 堆插入的 O(1) 平均情况复杂度的论证

c# - .NET List<T>.Sort 使用 introsort,为什么最坏的情况是 O(n^2)?

ruby - 处理任意不等式,并检查是否满足

javascript - 分配给变量时如何将方法绑定(bind)到原始上下文

javascript - 如何使用 jquery 克隆多个 html 输入字段

javascript - 将数组转换为包含对象

c++ - 如何计算均值(平均)robuSTLy?

algorithm - 如何计算搜索图形的最小预期时间?