数组迭代和宽松增量

时间:2016-01-18 22:52:19

标签: javascript jquery css arrays easing

我正在尝试创建一个迭代数组的函数,并将值递增一定量。随着值变大,值递增的量必须减少。

请考虑以下事项:

// Before first iteration
['100','150','220','280','310','330']

// After first iteration
['106','155','224','283','312','331']

// After second iteration
['112','160','228','288','314','332']

// After third iteration (note the last item has been reset to 100)
['100','117','164','232','291','316']

在上面的示例中,我使用了增量#6; 6,5,4,3,2,1和#39;但这些数字的问题在于它们最终会相互追赶。我正在努力计算要使用的正确值,这将确保值更接近数组的末尾,但值不会相互重叠。

为了重新考虑,这里的问题不一定是创建值数组,而是创建一个值数组来维持我想要的缓动,即环朝屏幕边缘靠近在一起,同时防止戒指最终相互追赶并重叠......

为了进一步复杂化,每当一个值超过332时,它需要重置为100.这将基本上移动外面的任何环,回到内部......

这些值最终会形成一个函数的基础,它将创建如下内容:

Circles Example

增量金额将是为戒指大小设置动画的金额。我会在CSS中编写动画,但不幸的是动画将是事件驱动的,并且通过事件驱动我的意思是多点触摸事件驱动因此JavaScript是我唯一的选择......

我的代码

我已经玩了很多代码,但我真的很难理解算法和价值观!这是我目前所拥有的,但它无法正常工作:

// Calculate the properties for each ring
for(var i=0;i<6;i++){
    var ring_decrement = 6-i;
    ring_properties[i].dimension += ((-2.5 * ((t=(ring_decrement/10)-1)*t*t*t - 1) + 0.1)/100)*container_width;
    ring_properties[i].opacity = i===0 ? 0 : i===1 ? 0.7 : Math.round((0.6-(i/10))*10)/10;
    if(((ring_properties[i].dimension/container_width)*100)>80){
        ring_properties[i].dimension = 100;
        ring_properties[i].opacity = 0;
    }
}
ring_properties.sort(function(a,b){
    if(a.dimension===b.dimension){
        return 0;
    }else{
        return (parseInt(a.dimension)<parseInt(b.dimension)) ? -1 : 1;
    }
});
// Apply the properties to the rings
$('.radius_ring').each(function(i){
    /*if(ring_properties[i].dimension===100){
        $(this).addClass('paused');
    }*/
    $(this).css({
        width: ring_properties[i].dimension+'px',
        height: ring_properties[i].dimension+'px',
        opacity: ring_properties[i].opacity
    });
});

以下是创建初始响铃的代码(此代码有效!):

var ring_dimension_percent = 5;
var ring_explode_increment = 0;
var container_width = parseInt($('#scan_radius_container').css('width'));
var ring_properties = new Array();

// Explode radius rings on load
var ring_explode = setInterval(function(){
    // Calculate the percentage of the container width
    ring_dimension_percent = ring_explode_increment===0 ? ring_dimension_percent : Math.round(-75 * ((t=(ring_explode_increment/10)-1)*t*t*t - 1) + 10);
    // Translate the percentage into pixels
    ring_properties[ring_explode_increment] = {
        // Set the dimension
        dimension: (ring_dimension_percent/100)*container_width,
        // Set the opacity
        opacity: ring_explode_increment===0 ? 0 : ring_explode_increment===1 ? 0.7 :  Math.round((0.6-(ring_explode_increment/10))*10)/10
    };
    // Apply the styles to the radius rings
    $('.radius_ring:eq('+ring_explode_increment+')').css({
        width: ring_properties[ring_explode_increment].dimension+'px',
        height: ring_properties[ring_explode_increment].dimension+'px',
        opacity: ring_properties[ring_explode_increment].opacity
    });
    if($('.radius_ring').length===(ring_explode_increment+1)){
        clearInterval(ring_explode);
    }else{
        ring_explode_increment++;
    }
},50);

1 个答案:

答案 0 :(得分:1)

编辑以解决有关追赶/重叠的行的评论

您可以做的一件事是为递增数组使用正弦函数。也就是说,将[0º,90º]的范围分成六个部分[0, 15, 30, 45, 60, 75],然后每次将这些度数增加一。使用这些值的sine来计算半径。

这里有一些代码可以让它更清晰。

var DEG_TO_RADIAN = Math.PI / 180; // convert degrees to radian
var minRadius = 100;
var maxRadius = 340;
var degrees = [0, 15, 30, 45, 60, 75];
var radius = new Array(6);

function incrementArray(){
  degrees.forEach(function(d, i){
    degrees[i] = (degrees[i] + 1) % 90; // so it's always between [0,90]
    var radian = degrees[i] * DEG_TO_RADIAN;
    var sine = Math.sin(radian); 
    // bound the radius so it's between min and max allowed radius
    // and convert to integer value.
    radius[i] = Math.round(minRadius + sine * (maxRadius - minRadius));
  });

  console.log("Radius = " + radius.join(","))
}

setInterval(incrementArray, 50)

以下是bl.ock with a sample animationthe corresponding gist

以前的答案。请忽略......不解决具体问题。

这样可行,但你需要修改它以完成你正在做的所有其他额外的事情。

arr = [100, 150, 220, 280, 310, 330];
increments = [6, 5, 4, 3, 2, 1];
allowedMax = 332; // reset to 100 once we hit this

function incrementArray(){
  arr.forEach(function(d, i){
    arr[i] += increments[i];
    if(arr[i] > allowedMax){
      arr[i] = 100;
    }
  });
  arr.sort(); // sort ascending.
  console.log(arr) // print so we can see that it makes sense
}

// increment every 1 second
setInterval(incrementArray, 1000)