Поворот списка <li>изображений, размещенных по кругу, по клику любого ребенка в заданную позицию - PullRequest
0 голосов
/ 25 мая 2019

Я упорядочил список изображений по кругу, используя преобразования CSS. я хочу, чтобы при щелчке по любому дочернему изображению из списка круг вращался, а выбранное или активное дочернее изображение доходило до заданной позиции. скажи 3 часа. Как я могу добиться этого с JS. я не знаю sass в настоящее время

это то, что я получил прямо сейчас.

! https://ibb.co/zfPQvNn

когда нажимается любое дочернее изображение, я хочу, чтобы круг вращался так, чтобы активное изображение всегда оказывалось в одной и той же позиции. скажи 3 часа

<div class="team-list">
    <ul>
       <li class="wow active zoomIn" data-wow-duration="1s" data-wow-delay=".1s">
            <a href="#team-1" data-team="team-1">
               <figure>
                      <img src="https://dummyimage.com/640x4:3/" alt="Team Member image One">
               </figure>
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".3s">
            <a href="#team-2" data-team="team-2">
               <figure>
                       <img src="https://dummyimage.com/640x4:3/" alt="Team Member image two">
               </figure>
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".5s">
            <a href="#team-3" data-team="team-3">
               <figure>
                      <img src="https://dummyimage.com/640x4:3/" alt="Team Member image three">
              </figure>
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".7s">
            <a href="#team-4" data-team="team-4">
               <figure>
                      <img src="https://dummyimage.com/640x4:3/" alt="Team Member image four">
               </figure>
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".9s">
            <a href="#team-5" data-team="team-5">
               <figure>
                      <img src="https://dummyimage.com/640x4:3/" alt="Team Member image five">
              </figure>
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.1s">
            <a href="#team-6" data-team="team-6">
               <figure>
                      <img src="https://dummyimage.com/640x4:3/" alt="Team Member image six">
               </figure>
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.3s">
            <a href="#team-7" data-team="team-7">
               <figure>
                       <img src="https://dummyimage.com/640x4:3/" alt="Team Member image seven">
               </figure>
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.5s">
            <a href="#team-8" data-team="team-8">
               <figure>
                       <img src="https://dummyimage.com/640x4:3/" alt="Team Member image eight">
               </figure>
            </a>
        </li>
     </ul>      
</div>


.team-list > ul > * {
  /* 4 */
  display: block;
  position: absolute;
  margin-top:55%;

}
.team-list > ul > :nth-of-type(1) {
  transform: rotate(0deg) translate(10em) rotate(0deg);
}
.team-list >ul > :nth-of-type(2) {
  transform: rotate(45deg) translate(10em) rotate(-45deg);
}
.team-list > ul > :nth-of-type(3) {
  transform: rotate(90deg) translate(10em) rotate(-90deg);
}
.team-list > ul > :nth-of-type(4) {
  transform: rotate(135deg) translate(10em) rotate(-135deg);
}
.team-list > ul > :nth-of-type(5) {
  transform: rotate(180deg) translate(10em) rotate(-180deg);
}
.team-list > ul > :nth-of-type(6) {
  transform: rotate(225deg) translate(10em) rotate(-225deg);
}
.team-list > ul > :nth-of-type(7) {
  transform: rotate(270deg) translate(10em) rotate(-270deg);
}
.team-list > ul > :nth-of-type(8) {
  transform: rotate(315deg) translate(10em) rotate(-315deg);
}

.team-list img {
  display: block;
  width: 100%;
}

1 Ответ

0 голосов
/ 26 мая 2019

Вариант 1

Один из способов сделать это - «передать» свойство transform по элементам каждый раз, когда пользователь щелкает по нему, получая эффект несколько привлекательный, но не совсем чистый поворот. Это можно сделать с помощью функции getComputedStyle , например:

let allItems = document.getElementById('list').getElementsByTagName('li');
let allItemsAsArray = Array.from(allItems);

let fixedPositions = {}, transforms = {};
let auxPosition = 0;

allItemsAsArray.forEach((elem, index) => {
  transforms[auxPosition] = window.getComputedStyle(elem).transform;
  fixedPositions[index] = auxPosition++;

  elem.addEventListener('click', (event) => {
    let steps = 8 - fixedPositions[index];
    allItemsAsArray.forEach((elem2, index2) => {
          copyTransformProp(
              transforms[fixedPositions[(index2 + steps) % 8]]
            ,
          elem2);
    });
  });
});

function copyTransformProp(sourceProperty, targetNode) {  
  targetNode.style.setProperty('transform', sourceProperty);
}
.team-list > ul > li {
  /* 4 */
  display: block;
  position: absolute;
  top:55%;
  left: 40%;
  transition: ease all 1s;
}

#list img {
  width: 50px
}

.team-list > ul > :nth-of-type(1) {
  transform: rotate(0deg) translate(10em) rotate(0deg);
}

.team-list >ul > :nth-of-type(2) {
  transform: rotate(45deg) translate(10em) rotate(-45deg);
}

.team-list > ul > :nth-of-type(3) {
  transform: rotate(90deg) translate(10em) rotate(-90deg);
}

.team-list > ul > :nth-of-type(4) {
  transform: rotate(135deg) translate(10em) rotate(-135deg);
}
.team-list > ul > :nth-of-type(5) {
  transform: rotate(180deg) translate(10em) rotate(-180deg);
}
.team-list > ul > :nth-of-type(6) {
  transform: rotate(225deg) translate(10em) rotate(-225deg);
}
.team-list > ul > :nth-of-type(7) {
  transform: rotate(270deg) translate(10em) rotate(-270deg);
}
.team-list > ul > :nth-of-type(8) {
  transform: rotate(315deg) translate(10em) rotate(-315deg);
}

.team-list img {
  display: block;
  width: 20%;
}
<div class="team-list">
    <ul id='list'>
       <li class="wow active zoomIn" data-wow-duration="1s" data-wow-delay=".1s" >
            <a href="#team-1" data-team="team-1">
               
                      <img src="https://dummyimage.com/640x4:3/&text=1" alt="Team Member image One">
               
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".3s">
            <a href="#team-2" data-team="team-2">
               
                       <img src="https://dummyimage.com/640x4:3/&text=2" alt="Team Member image two">
               
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".5s">
            <a href="#team-3" data-team="team-3">
               
                      <img src="https://dummyimage.com/640x4:3/&text=3" alt="Team Member image three">
              
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".7s">
            <a href="#team-4" data-team="team-4">
               
                      <img src="https://dummyimage.com/640x4:3/&text=4" alt="Team Member image four">
               
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".9s">
            <a href="#team-5" data-team="team-5">
               
                      <img src="https://dummyimage.com/640x4:3/&text=5" alt="Team Member image five">
              
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.1s">
            <a href="#team-6" data-team="team-6">
               
                      <img src="https://dummyimage.com/640x4:3/&text=6" alt="Team Member image six">
               
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.3s">
            <a href="#team-7" data-team="team-7">
               
                       <img src="https://dummyimage.com/640x4:3/&text=7" alt="Team Member image seven">
               
            </a>
        </li>
        <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.5s">
            <a href="#team-8" data-team="team-8">
               
                       <img src="https://dummyimage.com/640x4:3/&text=8" alt="Team Member image eight">
               
            </a>
        </li>
     </ul>      
</div>

Вариант 2

Теперь, чтобы добиться действительно чистого вращения, я бы пошел с запросом кадра анимации. . На этот раз вы не зависите от свойства CSS transition для гладкости, но напрямую от JavaScript, работающего с углами.

Я подумал, что было бы лучше генерировать элементы динамически в JS, поэтому вам не нужно стилизовать каждый из них вручную в CSS. Это также позволяет вам генерировать «столько предметов, сколько вы хотите», однако, будьте осторожны, не жадничайте от суммы.

Попробуйте этот фрагмент полной страницы.

Е.И.В.

let ul = document.getElementById('list');
let anglePerItem = [];

generateItems(8, 0, 9);

let allItems = ul.getElementsByTagName('li');
let allItemsAsArray = Array.from(allItems);

function generateItems(itemNum, initAngle, radius) {
    let angleStep = Math.PI * 2 / itemNum;
    let angle = initAngle;

    for (let i = 0; i < itemNum; i++) {
        let li = document.createElement('li');
        if (i === 0)
            li.classList.add('wow', 'active', 'zoomIn');
        else
            li.classList.add('wow', 'zoomIn');

        let a = document.createElement('a');
        a.href = '#team-' + (i + 1);
        a.setAttribute('data-team', 'team-' + (i + 1));
        li.appendChild(a);

        let img = document.createElement('img');
        img.src = 'https://dummyimage.com/640x4:3/&text=' + (i + 1);
        img.alt = 'Team Member image ' + (i + 1);
        a.appendChild(img);

        let x = Math.cos(angle) * radius, y = Math.sin(angle) * radius;
        anglePerItem.push(angle);
        angle += angleStep;
        li.style.transform = 'translate(' + x + 'em, ' + y + 'em)';

        ul.appendChild(li);

        addClickEvent(li, i, radius);
    }
}

function addClickEvent(elem, clickedIndex, radius) {
    elem.addEventListener('click', () => {
        if (anglePerItem[clickedIndex] !== 0) {
            Array.from(ul.getElementsByTagName('li')).forEach((elem, index) => {
                let angle = anglePerItem[index] % (Math.PI * 2);
                let endAngle = Math.PI * 2 - anglePerItem[clickedIndex] + angle;
                if (angle > endAngle)
                    endAngle += Math.PI * 2;

                function step(timestamp) {
                    let x = Math.cos(angle) * radius, y = Math.sin(angle) * radius;
                    angle += .1;

                    elem.style.transform = 'translate(' + x + 'em, ' + y + 'em)';

                    if (angle < endAngle) {
                        setTimeout(function () {
                            window.requestAnimationFrame(step);
                        }, 10);
                    } else {
                        elem.style.transform = 'translate(' + Math.cos(endAngle) * radius + 'em, ' + Math.sin(endAngle) * radius + 'em)';
                        anglePerItem[index] = endAngle;
                    }
                }

                window.requestAnimationFrame(step);
            });
        }
    });
}
.team-list > ul > li {
    display: block;
    position: absolute;
    top:50%;
    left: 40%;
}

#list img {
    width: 50px
}

.team-list img {
    display: block;
    width: 20%;
}
<div class="team-list"><ul id='list'></ul></div>
...