I am currently working on a function that involves iterating over an array and incrementing the values by varying amounts. The challenge is to decrease these incremental amounts as the values in the array get larger.
Let's consider the following example:
// Original array
['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']
In the given scenario, I utilized sequential incremental amounts of '6,5,4,3,2,1'. However, with these specific numbers, there is a risk of overlap among the values as they progress. The main challenge lies in determining the correct values to ensure that the elements are closer together towards the end of the array without overlapping.
To reiterate, the issue at hand isn't solely about generating an array of values; instead, it revolves around creating a set of values that maintain the desired easing effect - drawing the elements closer near the boundary of the screen, while avoiding any overlaps or catch-up situations...
Adding further complexity, any value exceeding 332 must be reset back to 100. This action essentially shifts the outermost rings back towards the center...
These calculated values will serve as the foundation for a function that aims to create something similar to the image below:
https://i.sstatic.net/N7e6O.png
The incremental values will dictate the animation sizing for the rings. While CSS seems like a viable option, event-driven multi-touch animations necessitate the use of JavaScript.
My Approach
Despite numerous attempts, I'm struggling to devise the appropriate algorithm and values for this operation! Below is my current implementation that unfortunately does not yield the desired outcome:
// Calculating 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;
}
});
// Applying 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
});
});
Furthermore, here is the code segment responsible for initializing the rings (which currently functions as expected):
var ring_dimension_percent = 5;
var ring_explode_increment = 0;
var container_width = parseInt($('#scan_radius_container').css('width'));
var ring_properties = new Array();
// Trigger radius ring expansion on load
var ring_explode = setInterval(function(){
// Calculating 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);
// Conversion from percentage to pixels
ring_properties[ring_explode_increment] = {
dimension: (ring_dimension_percent/100)*container_width,
opacity: ring_explode_increment===0 ? 0 : ring_explode_increment===1 ? 0.7 : Math.round((0.6-(ring_explode_increment/10))*10)/10
};
// Application of 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);