I have to show Array values in circle kind of shape and it has to be run in a loop forever. Things are working fine when you rotate circle counter clockwise. But it has a problem in when we move circle in opposite direction.
I have an active element on the wheel. So when you user clicks on any other slide then active it calculates the difference between clicked slide and active slide then add and remove items in wheel accordingly.
So basically it picks the value from Array. if you move circle clockwise it picks values from the back of the Array and if you move it counterclockwise it starts picking up values from next available. If 11 items are rendered in first-page load then it will start taking values from 12 no index.
The problem occurs when you click the item which has above position from the active element and then you again rotates it counterclockwise.
Let say you click item no. 8 then you click item no.7. In this case item, no.2 should have been added into the wheel.
Here is fiddle.
var numberOfElement = [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];
var initialRender = numberOfElement.slice(0, 11);
var startPoint = initialRender.length;
var endPoint = numberOfElement.length;
function generateHtml() {
var html = '';
initialRender.forEach(function(item, index) {
var angle = 18 * (index);
var className = angle === 90 ? 'active' : '';
html += '<div class="shapes ' + className + '" data-deg="' + angle + '" style="--deg:' + angle + 'deg;"> <span class="set-pos">' + (item) + '</span> <span> ' + angle + ' deg </span></div>';
})
document.querySelector('#dynamic-html').innerHTML = html;
}
generateHtml();
$('#dynamic-html').on('click', '.shapes', function() {
var deg = 90;
var activeDeg = $('.active').data('deg');
var needToremoveElement = activeDeg;
var selectedElement = $(this).data('deg');
var degrees = deg - selectedElement;
var diff = Math.abs((activeDeg - selectedElement) / 18);
$('.shapes').removeClass('active');
$(this).addClass('active');
var movementCloseWise = degrees > ($('.circle').data('deg') || 0);
$('.circle').removeData('deg');
$('.circle').css({
'transform': 'rotate(' + degrees + 'deg)'
}).attr('data-deg', degrees);
if (movementCloseWise) {
var itemLength = $('.shapes').length;
$('.shapes:gt(' + ((itemLength - 1) - diff) + ')').remove()
var newItems = generateItem(getItemsFromBack(diff), true);
newItems = $(newItems).get().reverse();
$('#dynamic-html').prepend(newItems)
startPoint -= diff;
} else {
var newItems = generateItem(getItemFromStart(diff), false)
$('#dynamic-html').append(newItems)
$('.shapes:lt(' + (diff) + ')').remove()
endPoint += diff;
}
})
function getItemsFromBack(length) {
var values = [];
endPoint = endPoint - length;
if (endPoint < 0) {
endPoint = numberOfElement.length - Math.abs(endPoint)
var otherVal = 0;
if (endPoint + length >= numberOfElement.length) {
otherVal = (endPoint + length) - numberOfElement.length;
values = numberOfElement.slice(endPoint, numberOfElement.length)
}
if (otherVal > 0) {
values = values.concat(numberOfElement.slice(0, otherVal))
}
} else {
values = numberOfElement.slice(endPoint, endPoint + length)
}
var valuesCount = values.length;
return values.reverse();
}
function getItemFromStart(length) {
var values = numberOfElement.slice(startPoint, startPoint + length);
var valueCount = values.length;
startPoint += valueCount;
if (valueCount < length) {
startPoint = 0;
return values.concat(getItemFromStart(length - valueCount));
} else if (startPoint >= numberOfElement.length) {
startPoint = 0;
}
return values;
}
function generateItem(items, isClockWise) {
var html = "",
lastItemAngle;
if (isClockWise) {
lastItemAngle = $('#dynamic-html .shapes:first').data('deg');
} else {
lastItemAngle = $('#dynamic-html .shapes:last').data('deg');
}
items.forEach(function(item, index) {
if (isClockWise) {
var angles = lastItemAngle - (18 * (index + 1))
} else {
var angles = lastItemAngle + (18 * (index + 1))
}
html += '<div class="shapes" data-deg="' + (angles) + '" style="--deg:' + angles + 'deg;"> <span class="set-pos">' + (item) + '</span> <span> ' + angles + ' deg </span></div>';
});
return html;
}
I think your problem is just your endPoint initialization value. In your code, you initialize it as var endPoint = numberOfElement.length; which is wrong( I think) and it should be initialized by 0; I changed it and it worked:
var numberOfElement = [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];
var initialRender = numberOfElement.slice(0,11);
var startPoint = initialRender.length;
var endPoint = 0; /* here is the change */
function generateHtml(){
var html ='';
initialRender.forEach(function(item,index){
var angle = 18 * (index);
var className = angle === 90? 'active':'';
html+='<div class="shapes '+className+'" data-deg="'+angle+'" style="--deg:'+angle+'deg;"> <span class="set-pos">'+(item)+'</span> <span> '+angle+' deg </span></div>';
})
document.querySelector('#dynamic-html').innerHTML= html;
}
generateHtml();
$('#dynamic-html').on('click','.shapes',function(){
var deg = 90;
var activeDeg = $('.active').data('deg');
var needToremoveElement = activeDeg;
var selectedElement = $(this).data('deg');
var degrees = deg - selectedElement;
var diff = Math.abs((activeDeg - selectedElement) / 18);
$('.shapes').removeClass('active');
$(this).addClass('active');
var movementCloseWise = degrees > ($('.circle').data('deg') || 0);
$('.circle').removeData('deg');
$('.circle').css({'transform' : 'rotate('+ degrees +'deg)'}).attr('data-deg',degrees);
if(movementCloseWise){
var itemLength = $('.shapes').length;
$('.shapes:gt('+((itemLength-1)-diff)+')').remove()
var newItems = generateItem(getItemsFromBack(diff), true);
newItems = $(newItems).get().reverse();
$('#dynamic-html').prepend(newItems)
startPoint -= diff;
}else{
var newItems = generateItem(getItemFromStart(diff), false)
$('#dynamic-html').append(newItems)
$('.shapes:lt('+(diff)+')').remove()
endPoint += diff;
}
})
function getItemsFromBack(length) {
var values = [];
endPoint = endPoint - length;
if (endPoint < 0) {
endPoint = numberOfElement.length - Math.abs(endPoint)
var otherVal = 0;
if (endPoint + length >= numberOfElement.length) {
otherVal = (endPoint + length) - numberOfElement.length;
values = numberOfElement.slice(endPoint, numberOfElement.length)
}
if (otherVal > 0) {
values = values.concat(numberOfElement.slice(0, otherVal))
}
} else {
values = numberOfElement.slice(endPoint, endPoint + length)
}
var valuesCount = values.length;
return values.reverse();
}
function getItemFromStart(length) {
var values = numberOfElement.slice(startPoint, startPoint + length);
var valueCount = values.length;
startPoint += valueCount;
if (valueCount < length) {
startPoint = 0;
return values.concat( getItemFromStart(length - valueCount) );
} else if (startPoint >= numberOfElement.length) {
startPoint = 0;
}
return values;
}
function generateItem (items, isClockWise){
var html = "", lastItemAngle;
if(isClockWise){
lastItemAngle = $('#dynamic-html .shapes:first').data('deg');
}
else{
lastItemAngle = $('#dynamic-html .shapes:last').data('deg');
}
items.forEach(function(item,index){
if(isClockWise){
var angles = lastItemAngle - (18 * (index +1))
}
else{
var angles = lastItemAngle + (18 * (index +1))
}
html+='<div class="shapes" data-deg="'+(angles)+'" style="--deg:'+angles+'deg;"> <span class="set-pos">'+(item)+'</span> <span> '+angles+' deg </span></div>';
});
return html;
}
.main{
display: flex;
justify-content: center;
align-items: center;
height: 500px;
}
.pos{
height:150px;
width:150px;
position: relative;
}
.circle{
background: red;
height:150px;
width:150px;
border-radius: 50%;
transition: transform 0.3s ease-in-out;
}
.shapes{
position: absolute;
top:calc(50% - 75px);
left:calc(50% - 10px);
width: 20px;
height: 150px;
transform: rotate(var(--deg)) translate(0, 160px);
background: green;
text-align: center;
}
.fake-overlay{
position: absolute;
width: 203%;
height: 320%;
background: #fff;
top: -160px;
right: -148%;
display: none
}
.active{
background: red
}
.set-pos{
position: absolute;
bottom: 0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div class="pos">
<div class="circle">
<div id="dynamic-html"></div>
</div>
<div class="fake-overlay"></div>
</div>
</div>
And here is Jsfiddle
I have fixed this by the following code.
function getItemsFromBack(length) {
var values = [];
if (endPoint > numberOfElement.length) {
var diff = endPoint - numberOfElement.length;
values = numberOfElement.slice(diff - length, diff)
endPoint = endPoint - length;
return values.reverse();
}
endPoint = endPoint - length;
if (endPoint < 0) {
endPoint = numberOfElement.length - Math.abs(endPoint)
var otherVal = 0;
if (endPoint + length >= numberOfElement.length) {
otherVal = (endPoint + length) - numberOfElement.length;
values = numberOfElement.slice(endPoint, numberOfElement.length)
}
if (otherVal > 0) {
values = values.concat(numberOfElement.slice(0, otherVal))
}
} else {
values = numberOfElement.slice(endPoint, endPoint + length)
}
var valuesCount = values.length;
return values.reverse();
}
I am checking if endPoint is greater then total Array length. Then endPoint- Array.length and using diff to get the element
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With